WP4.4 でサポートされたレスポンシブイメージの機能がどんなものなのか実験してみました
srcset と sizes 属性
WP4.4 から記事中に使用しているメディアライブラリに登録されている画像を閲覧者のブラウザに最適に表示させることが出来る機能が追加されました
この機能を使うと、閲覧者のブラウザがサポートしているなら、ブラウザがより最適な画像を選択することで画像データ通信量の減少とレスポンスの高速化が期待できます
先ずはどのような機能なのかを下記テーマと画像を使って確認してみます
- 使用画像 : 1920×1080
- テーマ : Twentysixteen
- ブラウザ : chrome ver 47.0.2526.80 m
実験1.フルサイズ画像を挿入
ちょっと画像ではわかりづらいですが、フルサイズ(1920×1080)を指定した時に 768×432 サイズの画像が使われました
何が行われているのかと言うと、これは img タグの src に今までどおりに指定した画像がセットされますが、合わせて srcset と sizes という属性がセットされているのが分かります
ネットワークを確認してみると 768サイズの画像データの通信が行われたことが確認出来ます
このようにブラウザによって最適な画像を選択してもらうための機能が働いたことがわかります
それでは、もう少しく詳しく見ていきます
srcset
srcset は使用可能な画像リストです
wordpressは、画像がメディアライブラリに登録されるときに、標準で大(large)サイズ、中(medium)サイズ、サムネイル(thumbnail)サイズの画像を生成していました。更にWP4.4 からは中大(medium_large)サイズが内部的に生成されて追加されました(但し設定パネルには表示されない)。
srcset 画像リストに含まれるのは、この4種類と元画像のフルサイズの画像、更にテーマで独自に追加した画像サイズとなります
但し、srcset に含める最大画像幅はデフォルトで 1600px までとなり、指定画像と縦横比が同じ画像のみという制限を設けているようです
従って、この例ではテーマで追加している 1200px 画像が含まれますが、元画像の 1920px は含まれません。また、サムネイル画像もクリッピングしていると縦横比が変わってしまいますので含まれません。
従って img タグの中身はこんな感じになっています(見やすいように整形してます)
<img class="wp-image-3689 size-full" src="http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024.jpg" alt="SN3Q0024" width="1920" height="1080" srcset="http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024-300x169.jpg 300w, http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024-768x432.jpg 768w, http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024-1024x576.jpg 1024w, http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024-1200x675.jpg 1200w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" />
この srcset が選択可能な画像リストとなります
sizes
次にブラウザにどの画像を選択すべきなのかを教えてあげる必要があります
それが sizes 属性で、メディアクエリーとビューポートの割合を定義しています
ビューポートは、ブラウザ表示領域でスクロールバーを含んだサイズとなり、幅を表す時は vw という相対的な単位で指定します。スクロールバーを含んだ全幅サイズが 100vw となります。
vw の値は、スクロールバーを含むので HTML の表示領域を % で示した値と若干異なるので % ではなく vw という単位で明確に区別していると思われますが、%値より若干大きなサイズと思っていればほぼほぼ同じようなものです
この例ではビューポートのサイズに基づいてメディアクエリを以下の4種類に分けています
709px 以下 | 85 vw |
710 – 909 px | 67 vw |
910 – 1362 px | 62 vw |
1363 px 以上 | 840 px |
従って、今回の例ではビューポート(ブラウザ幅)が 1112 px の場合ならば 62% に当たる 688 pxの画像を選択してくださいとブラウザへ伝えていることとなります
ブラウザで srcset をサポートしていなければフルサイズの画像が使われますが、サポートしているなら 768px サイズの画像が選択されることを期待しています
この辺りの仕組みについては srcset と sizes サイトが分かりやすいです
ちなみに、この sizes に書き出される値は、Twenttsixteen テーマの function.php で wp_caluculate_image_sizes にフィルターフックしてセットしています
アイキャッチに対しても指定できるようです
/** * Add custom image sizes attribute to enhance responsive image functionality * for content images * * @since Twenty Sixteen 1.0 * * @param string $sizes A source size value for use in a 'sizes' attribute. * @param array $size Image size. Accepts an array of width and height * values in pixels (in that order). * @return string A source size value for use in a content image 'sizes' attribute. */ function twentysixteen_content_image_sizes_attr( $sizes, $size ) { $width = $size[0]; 840 <= $width && $sizes = '(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px'; if ( 'page' === get_post_type() ) { 840 > $width && $sizes = '(max-width: ' . $width . 'px) 85vw, ' . $width . 'px'; } else { 840 > $width && 600 <= $width && $sizes = '(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px'; 600 > $width && $sizes = '(max-width: ' . $width . 'px) 85vw, ' . $width . 'px'; } return $sizes; } add_filter( 'wp_calculate_image_sizes', 'twentysixteen_content_image_sizes_attr', 10 , 2 ); /** * Add custom image sizes attribute to enhance responsive image functionality * for post thumbnails * * @since Twenty Sixteen 1.0 * * @param array $attr Attributes for the image markup. * @param int $attachment Image attachment ID. * @param array $size Registered image size or flat array of height and width dimensions. * @return string A source size value for use in a post thumbnail 'sizes' attribute. */ function twentysixteen_post_thumbnail_sizes_attr( $attr, $attachment, $size ) { if ( 'post-thumbnail' === $size ) { is_active_sidebar( 'sidebar-1' ) && $attr['sizes'] = '(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 60vw, (max-width: 1362px) 62vw, 840px'; ! is_active_sidebar( 'sidebar-1' ) && $attr['sizes'] = '(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 88vw, 1200px'; } return $attr; } add_filter( 'wp_get_attachment_image_attributes', 'twentysixteen_post_thumbnail_sizes_attr', 10 , 3 );
既存のテーマでは、特に記述しなくともデフォルトでコンテント幅から適当に処理してくれるようですが、より最適な画像の選択を行いたい場合には、テーマでメディアクエリーの分岐サイズに合わせた画像サイズの指定をしてあげる必要があります
テーマ側の対応に関してはこの辺りの記事が参考になります
Responsive Images in WordPress 4.4
実験2.コンテンツ幅より小さなサイズ画像を挿入
img タグの src には指定した中サイズの画像がセットされて、ブラウザでも指定通りの 300px サイズの画像が使われています
srcset はこんな感じです
<img class="wp-image-3689 size-medium" src="http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024-300x169.jpg" alt="SN3Q0024" width="300" height="169" srcset="http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024-300x169.jpg 300w, http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024-768x432.jpg 768w, http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024-1024x576.jpg 1024w, http://localhost/wordpress/wp-content/uploads/2015/12/SN3Q0024-1200x675.jpg 1200w" sizes="(max-width: 300px) 85vw, 300px" />
srcset の方は変わりませんが、sizes がビューポートが300以上なら300サイズ固定になるように変わりました
ネットワークで通信された画像データを見ても300サイズの画像データが通信されていて期待通りの動作が行われています
実験3.コンテンツ幅より大きなサイズ画像を挿入
コンテント幅より大きな大サイズ 1024 サイズを指定した場合をみてみます
この場合フルサイズを指定した場合と同様な結果になるのかと思いましたが、使用されたのは src で指定された 1024×576 サイズの画像です
ネットワークを確認してみると何か問題があるようです
ネットワークで見ると何故か 768 サイズの後に 1024 サイズの画像データも通信処理されています
ブラウザはおそらく 768 サイズの画像を選択したのですが、何らかの不具合がありその後に 1024 サイズも要求してしまっているように見えます
WP側の srcset, sizes の設定が良くないのか、ブラウザ側の不具合かはわかりませんが、期待通りの動作ではないようです
これでは、せっかくの srcset 機能でかえって転送データが多くなり無駄が生じてしまいます
ちなみに Chrome の iPhone5 のシュミレーション機能上では、フルサイズの画像を指定した場合でも 768 と 1024 サイズの2種類の画像が通信されていました。実機ではありませんのでなんとも言えませんが、現状ではまだ不具合があるような気がします
まとめ
期待通りに動作すれば非常に有効な機能ではあるのですが、主要な全てのブラウザで対応されているわけではありませんし、この実験からも少し不自然な動作も見受けられます
使用中のテーマでどのように動作するかよく確認することをお勧めします
WordPressやブラウザ側の修正が行われるまで(少なくとも最初の修正バージョン WP4.4.1が出るまで)様子を見たほうが良いかもしれません
既にWP4.4 に更新してしまって、srcsetが期待通りの動作をしていない場合は下記コードをテーマの functionphp に追加して、一時的に機能を止めておくことも可能です
function disable_srcset( $sources ) { return false; } add_filter( 'wp_calculate_image_srcset', 'disable_srcset' );