Contentful・Gatsby・Netlify構成のJAMstackブログの画像を最適化する(したかった・・・。)
📅 November 01, 2020
•⏱️7 min read
どうも、みなさんこんにちは。 ブログの画像を最適化したいおじさんです。
画像があると意外とスコアが下がるかも
最近JAMstackのブログいじるのに完全にハマっていて、日々時間を溶かしています。JAMstackっと言えば、SSGしているので、googleさんのPageSpeed Insightsを試しても、さぞいいスコアを叩き出してくれるのだろうと思い早速試してみました。
が、残念なことに、スコアは70点前後。
おい。Gatsby話が違うじゃないか状態なので、調べたところ、画像の表示にものすごく時間がかかっているとのこと。気になるので、色々調べてみました。ただ、根本的な改善はできてませんので、あしからず。
開発者ツールで、ネットワークの遅い環境を再現する
とはいえ、グーグル先生のPageSpeedで遅いと言われているものの、普通のWifi環境で表示するとそれなりに速いので、まずはクロームの開発者ツールを使って遅いネットワークを再現します。
開発者ツールを表示して、Disabled cacheと有効にして、キャッシュの使用を無効化します。 次に、Disabled cacheのお隣に、onlineと書かれたプルダウンメニューがあると思うので、こいつをクリックして、Slow 3Gを選択します。
そうすると、なんと言うことでしょう。サムネイルを表示するのに10秒近くかかるではありませんか。
Gatsby-imageの設定を変更する
気休めのeagerload設定
Gatsby公式で、画像の表示にはGatsby-imageというプラグインを使用することを推奨しています。 大体のスターターキットを使うとこいつがデフォルトで入っているかと思います。
Chromeのloading属性は、指定しなくてもデフォルトで"lazy"の挙動となりうる ~loading属性の落とし穴から学ぶ、機能拡張と初期値・デフォルト挙動の話~ - Qiita
どうも、何も設定しないとlazyloadされているっぽいので、明示的にeager指定に変更します。 gatsby-imageのコンポーネントで渡すだけなので簡単ですね。
<StyledImg fluid={heroImage.fluid} backgroundColor={'#eeeeee'} loading="eager" />
スマホでの表示に必ずスクリーン何に収まる画像はeager指定にして、 それ以外は、lazyとかにすると良さそうなのですが、面倒なので、すべてeagerにしてみました。
体感特に変化はなさそう。
スマホにリッチな画像を渡さない
そもそも、このブログにサムネイル画像いるのか?と言われるといらないのですが、なんか表示が遅いからサムネイルなしにするって言うのは悔しいので、サムネイルは消しません。
そもそもの表示される画像なのですが、contentfulのCDNで取得しているようです。
開発者ツールで詳しく見てみるとimg属性がこんな感じになってました。
<img sizes="100vw" srcset="//images.ctfassets.net/99bd0ff43dr2/5BT2u1gUmIycSAgAm0aoKO/0e7fa2bfd42dfad68c2c23a9a6d9682f/american-doggo.jpg?w=200&h=133&q=50 200w,
//images.ctfassets.net/99bd0ff43dr2/5BT2u1gUmIycSAgAm0aoKO/0e7fa2bfd42dfad68c2c23a9a6d9682f/american-doggo.jpg?w=400&h=266&q=50 400w,
//images.ctfassets.net/99bd0ff43dr2/5BT2u1gUmIycSAgAm0aoKO/0e7fa2bfd42dfad68c2c23a9a6d9682f/american-doggo.jpg?w=800&h=531&q=50 800w,
//images.ctfassets.net/99bd0ff43dr2/5BT2u1gUmIycSAgAm0aoKO/0e7fa2bfd42dfad68c2c23a9a6d9682f/american-doggo.jpg?w=1000&h=664&q=50 1000w" src="//images.ctfassets.net/99bd0ff43dr2/5BT2u1gUmIycSAgAm0aoKO/0e7fa2bfd42dfad68c2c23a9a6d9682f/american-doggo.jpg?w=800&q=50" alt="" loading="eager" style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center center; opacity: 1; transition: opacity 500ms ease 0s;">
超絶見ずらいですが、srcsetという聞き馴染みの無い属性がおり、その属性値は
{画像のurl} スクリーンワイド,
{画像のurl} スクリーンワイド,
{画像のurl} スクリーンワイド,
{画像のurl} スクリーンワイド,
となっとりました。 src属性だと、PCでもスマホでも同じ画像を表示してしまうのに対して、srcsetだと、ウィンドウサイズに応じた画像を出し分けてくれるようです。 詳しくはこちらを↓ レスポンシブ画像 - ウェブ開発を学ぶ | MDN
で、気になるスマホ時の画像表示を見てみると、iPhoneなどはRetinaディスプレイなので、PC画面と同じくらいの画像を参照していました。(このサイトだと、1000wの時の画像URLを参照していました。)
スマホだし、そんなリッチな画像じゃなくていいでしょってことで、雑にsizesを50vwにしました。
sizes="50vw"
こいつを指定すると、ウィンドウ幅の半分を基準に画像のソースを選択してくれるらしい。 詳しくは、こちらを↓。 HTMLのsrcsetを使って画像をレスポンシブにRetina対応させてみよう | Kia King
(PCだと、今は画面でかいので、問答無用でマックスに設定している、1000wが選ばれるので、まあいいかと。)
この辺りの、srcsetの作成処理は、gatsby-imageがやってくれてるみたいで、grapqlのqueryで
fluid(sizes: "50vw") {
を追加すると、sizesの指定ができるようです。
上がらないスコア
上記の設定変更で、3G slow の状態でリロードすると、画像の表示にかかる時間は、10秒かかっていたものが、4秒程度になりました。
やったー。
ただ、グーグル先生のページスピードでは、相変わらずと75点前後と、80点を超えられず・・・。 画像の最適化って難しい。
まだまだ、修行が足りないので精進します。
ホイジャーまたー。