「適切なサイズの画像」対策としてimgタグのsizes属性をいじってみた

WordPressは便利なもので、the_post_thumbnail関数を使うと、自動的に属性付きで<img>タグを出力してくれます。

属性っていうのは「src=”○○○”」とか「width=”○○○”」とか「alt=”○○○”」とか。

単にsrc属性だけじゃなくて、他のものもいい感じに出力してくれるところがNICE!

最近では「loading=”lazy”」も自動的に出力されるしね。

中でも推しているのは、srcset属性を出力してくれるところです。

srcset属性って自分で書くとめっちゃめんどいよね(笑

で、ここからが本題、せっかくsrcset属性を出力してくれて、画像タグ1つで画面幅に応じて適切な画像を設定しているのに、それがちゃんと活かせてなかったってことです。

そこでタイトルにあるように、sizes属性をいじってみることにしました。

srcset属性のメリットは?何が良いの?

srcset属性は長くなりがちだからごちゃごちゃする。

って言われたら確かにそうだけどorz

スマホで画像を表示させるならPC用の画像を縮小すればいいじゃん。

って言われたら確かに表現上は変化ないけどorz

でもね、srcset属性を指定することで、スマホとPCで別な画像を表示させられるんだよ!

メリットは多く分けて2つ。

  • スマホ用ページのサイズを抑えられる
  • PageSpeed Insights のスコアアップが期待できる

です。

スマホ用ページのサイズを抑えられるってどゆこと?

PageSpeed Insights の言葉を借りるなら、「モバイルデータ量を節約できる」ってことです。

よくCMで何ギガとか言ってるやつに関わることで、スマホ用ページのサイズが大きいと、読み込みが遅いのはもちろん、その“ギガ”消費量も増えます。

動画に比べればたかが知れてるかもしれないけど、訪問者にとってはストレスでしかないと思う。

運営者の立場としてもサボってるって言えないかな~。

PageSpeed Insights のスコアアップも期待できる

PageSpeed Insights ではファーストビューのスコアを計測しているので、オフスクリーンにある画像なら遅延読み込みしちゃえばぶっちゃけ影響はないです。

大事なのはファーストビューに表示される画像について。

そのファーストビューに表示される画像について、例えばロゴ画像とか記事のアイキャッチとか、srcsetでスマホ用に最適化された画像を表示させればスコアアップが期待できます。

「適切なサイズの画像」の警告が出る

そんな素敵なsrcset属性なんだけど、ちゃんと機能してなくない?

っていうのが問題。

例えば、記事一覧のサムネイル画像として、the_post_thumbnail関数で以下の様な画像タグが出力されたとします。

the_post_thumbnail関数で出力した画像

<img
  width="400"
  height="200"
  src="https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi-400x200.jpg"
  class="attachment-medium size-medium wp-post-image"
  alt="「ウェブフォント読み込み中のテキストの表示」は無視してOK!?"
  srcset="https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi-400x200.jpg 400w,
    https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi-768x384.jpg 768w,
    https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi-300x150.jpg 300w,
    https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi.jpg 800w"
  sizes="(max-width: 400px) 100vw, 400px"
/>

このようなタグが出力されたということは、

  • 幅300px なら https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi-300×150.jpg の画像
  • 幅400px なら https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi-400×200.jpg の画像
  • 幅768px なら https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi-768×384.jpg の画像
  • 幅800px なら https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi.jpg の画像(800×400px)

になるはずですが・・・。

PageSpeed Insights で計測すると「適切なサイズの画像」の警告が出ます。

詳細を確認すると、https://yws.tokyo/wp-content/uploads/2020/12/webfont-psi.jpg の画像、つまりスマホでも一番大きな 800×400px の画像が表示されています。

実際の表示領域としては、仮に 360×640 のデバイス幅だとして 134px 程度です。

スマホは高解像度だからある程度は大きい画像が表示されるのは全く問題ないけど、134px 程度の表示領域に対して 800px の画像が表示されるのは確かに大きすぎる。

sizes属性は出力されてるけど?

原因は、the_post_thumbnail関数が出力する、sizes属性と実際に表示される画像の表示領域が異なることです。

上の例では以下のように出力されています。

sizes="(max-width: 400px) 100vw, 400px"

これの意味は、

画面幅400pxまでは画面幅は100%、それ以上の場合は400pxの画像を表示する

という意味です。

▼以下の記事に詳しいことが書いてあります。
https://www.tagindex.com/html5/embed/img_srcset_sizes.html

最大でも400pxで表示されるなら800pxの大きな画像が表示されるわけないじゃん!

って思うかも知れないけど、PageSpeed Insights ではスマホ用の高解像度ディスプレイを意識して、実際の表示領域に対して2倍以上の画像解像度で測定しているのでしょう。

ここで一度整理すると、

  • PageSpeed Insights (モバイル)では2倍以上の画像解像度で測定される
  • 問題点は134px 程度の表示領域に対して 800px の画像が表示されること

という感じ。

134px に対して 800px っていうと、6倍くらいになるからやっぱり問題です。

300px とか、せめて 400px の画像が表示されて欲しいところ。

sizes属性をいじる

「適切なサイズの画像」の警告が出る問題を sizes属性 をいじることで解決してみました。

そもそも問題なのは、実際の表示は以下のように画面幅に対して100%ではないのに、

sizes属性では100vw、つまり100%としているところです。

なので、実際の表示領域通り40vw、つまり40%に変更してみると・・・。

sizes="(max-width: 400px) 40vw, 400px"

無事、「適切なサイズの画像」の警告は消えたとさ。

でね、わたしの環境が悪いのかも知れないけど、表示の確認は実機でやった方が間違いないです。

Chromeのデベロッパーツールで見てみると、srcset属性やsizes属性を設定していても、意図しない画像が表示されてしまいました。

※2020年12月現在

Chromeで見てて、おかしいな~って考えてたけど、実機で見たら普通に反映された(*´ω`*)

sizes属性を変更するには?

方法は以下が考えられます。

  • the_post_thumbnailでフィルターをかける
  • wp_calculate_image_sizesでフィルターをかける
  • get_the_post_thumbnailで取得したものを加工する

中でもわたしは「the_post_thumbnailでフィルターをかける」で変更しています。

以下の様な感じです。

function yws_sizes_replace( $html ) {

	$html = str_replace('100vw', '40vw', $html );
	return $html;

}
add_filter( 'post_thumbnail_html', 'yws_sizes_replace' );

「wp_calculate_image_sizesでフィルターをかける」についてもほぼ同じです。

ずっとthe_post_thumbnailにフィルターしてたんだけど、今回記事を書く時に調べ事をしていて偶然見つけました(笑

以下の様に post_thumbnail_html を wp_calculate_image_sizes に変えても結果は感じです。

function yws_sizes_replace( $html ) {

	$html = str_replace('100vw', '40vw', $html );
	return $html;

}
add_filter( 'wp_calculate_image_sizes', 'yws_sizes_replace' );

両者の違いは、

the_post_thumbnail → the_post_thumbnail関数で出力される画像に対して有効
wp_calculate_image_sizes → 全ての画像(?)に対して有効

って感じかなと思います。

the_post_thumbnail だと記事一覧のサムネイルとかだけどだけど、wp_calculate_image_sizes にすると記事中の画像のsizes属性も変わってしまいました。

「get_the_post_thumbnailで取得したものを加工する」っていうのは、特定の箇所に表示される画像のみ、sizes属性をいじりたい時に有効です。

スマホ用の画像を設定する方法は他にもあるけど

ここまではimgタグの srcset属性 でPCとスマホの画像を変える方法について話してきたけど、他にも切り替える方法はあります。

まず、cssのメディアクエリで切り替える方法。

PC時は400px、スマホ時は200pxとかじゃないよ。

これじゃ読み込む画像は変わらないから。

PCとスマホで別々な画像を表示させるってことね。

画像表示の仕方として、CSSのbackgroundを使うこともあるだろうし、これはこれでいいと思う。

ただ、サイト全体で見た時、画像1つ1つをメディアクエリで別の画像を表示させるのは合理的じゃない気がする。

wp_is_mobile() で振り分ける方法も同じかな。

こっちはページキャッシュのことを考えると、後々ボトルネックになる気がする。

そういったことを踏まえて、例えば自作テーマのスライダー画像は最初CSSのbackgroundで表示させていたんだけれど、今はimgタグのsrcset属性で切り替えるようにしています。

CSSのbackgroundだと、「スマホ時の画像はこちらに設定してください」とか言って設定してもらうことになるから、そこに労力がかかるし、ユーザーからしても設定が手間になると思って。

imgタグのsrcset属性だと、「スマホ用の画像は・・・」とか言う必要自体なくなるから、いろんな意味で効率的(*‘∀‘)b

あとがき

鍋を焦がしてしまい超ブルーです。

IHの卓上コンロでいつものように鍋を作っていたのですが・・・

どうも鍋の底が何らかの理由で変形?していたっぽく、熱が偏って伝わってしまったようで。

最初はちょっと香ばしい匂いかな~、くらいだったけど、食べてみると味がおかしい(>_<)

強い苦みを感じてようやく異変に気付きました。

やってしまった(ノД`)・゜・。

とは言え食材がもったいないので我慢して食べ続けるしかない。。。

最初はお腹空いてるから何とか食べられたけど、ある程度食べたところで具合が悪くなりました。

IHの卓上コンロも焦げ付いちゃったし。

┐(´д`)┌ヤレヤレ