Search Console をチェックしていたら、すべてのページが PC「改善が必要」 、 モバイル「不良」 のアラートが出てました汗。
コアウェブバイタル3つの指標のうち、CLS が 0.25 超!???今までは悪くても 1.0 超だったのに。
- LCP(Largest Contentful Paint) 一番大きいコンテンツ(画像やテキスト)が時間をかけずに表示されるか
- FID(First Input Delay) ユーザーがページ内で初めてクリック等のアクションを起こした際の応答時間
- CLS(Cumulative Layout Shift) 予期しないページレイアウトのずれが起きないか
早速 PageSpeed Insights でチェックすると、パフォーマンス評価がいつの間にかモバイル21まで落ちていて驚愕しました。
改善前のPageSpeed Insightsによるパフォーマンス評価
パソコン | モバイル |
---|---|
69/100 | 21/100 |
このWebサイトはそもそもスピード改善のために2年位前に静的サイトジェネレータに苦労して移行しました。
静的ジェネレータだしほっといても大丈夫と思い、特に何もしてなかったです。
絶望的だったのですが、、、
PageSpeed Insights のアラートを解消したら、ボトルネックだった CLSは0 になりました!
この記事ではフロントエンド側でできることを中心に、PageSpeed Insights のパフォーマンス評価をモバイルで 最大40以上スコアアップし改善した方法 をご紹介します。
トップページは記事とは違ってコンテンツは少ないので、PC版ではパフォーマンス100まで行きました!
CLS(Cumulative Layout Shift)の改善
画像や広告などが遅れて読み込まれ、突然レイアウトがズレたり変わったりする現象のことを レイアウトシフト と呼びます。
起きる原因としては、
- 読み込みが遅れた画像・動画等のメディアコンテンツ
- Webフォント
等です。
CLSはそのズレの大きさを指し、0.1未満が理想です。
※ CLS の数値「ずれが生じた表示領域の比率 × 距離の比率」
ちなみに 0.1以上で 改善が必要、 0.25 以上で 不良 となります。
チェックポイント
- 画像・動画等のheight・width属性などのサイズに関する記述漏れはないか?
- Reactなどの再レンダリングによるレイアウトシフトはおこっていないか
- Webフォントの読み込み対策はされているか?
Webフォントは今回 全ての指標に悪影響があったので使うのを諦めました。ベストプラクティスが見つかれば後日追記します。
画像・動画等のheight・width属性などのサイズを指定する
画像や動画(iframe含む)はheight・widthやアスペクト比を指定します。
<img src="****.png" width="400" height="300" alt="**">
<!-- もしくは -->
<img src="****.png" style="aspect-retio:4/3" alt="**">
CSSから直接指定してもOKです。
Reactなどによる再レンダリングを防ぐ
React のコンポーネントが再レンダリングされることによっておこることがあります。その場合は useMemo
を使って解決できることもあります。
useMemo
利用方法は以下記事に記載しています。
画像をギリギリまで小さくし、徹底的に圧縮
すべての指標において画像圧縮は即効性があります。
表示スピード改善には画像リサイズと圧縮が効果的。PageSpeed Insight のスコアが落ちたらすぐできる対策です。
チェックポイント
- 画像は可能な限り圧縮し、ギリギリまで小さくリサイズする
- 画像フォーマットは適切なものを使う
picture
タグを使ってユーザーの環境に応じて画像を出し分ける- スクロールするまで表示されない画像には
loading=lazy
やdecoding=async
を付与する
画像は可能な限り圧縮し、ギリギリまで小さくリサイズする
オンライン画像圧縮サービス、Photoshop など何でもツールはあるので使いやすいものを使って圧縮します。
私のケースではCLスクリプトを使ってまとめて画像を圧縮します。
画像は圧縮したから適切とは限りません。元画像が大きいと限界があります。表示場所に適切なサイズにリサイズも行います。
リサイズもオンラインやソフトなどいくらでもあります。お好みのツールを使ってください。
画像フォーマットは適切なものを使う
画像の種類によってフォーマットを使い分けます。
フォーマットの使い分けの基本は主にはPNGとJPEGです。
使い分けの目安としては色数が少ないのっぺりした画像はPNG、写真のような色数が細かいは JPEG にするようにしています。
また、最近では IE のことも気にしなくて良くなり、Safari にも対応したので WebP も積極的に使うようにしています。
GatsbyImage を使う場合
プロパティ | 値 |
---|---|
gatsbyImageData | width: 400 |
quality | 40 |
アイキャッチは最大表示より大きくならないようにし、さらに画質を落とす設定をしています。
ただ、GatsbyImage は画像出力もJSが使われているので少なからず負荷はかかります。
小さく、画層サイズの切り替えなど必要ないサムネイルに関しては、切り替えの必要のない場合は GatsbyImage を使わず、固 定サイズにする等設置する場所によって変えました。
<img
src="****.WebP"
alt="***"
width="254"
height="190"
loading="lazy"
decoding="async"
/>
GIFアニメ は古い。画像フォーマットを WebP に変える
GIFアニメ はサイトの表示スピードを遅くする原因となります。
GIFアニメを使っていましたが、 WebPアニメーションに変更しました。
アニメ画像に変換する君 というフリーソフトをICSメディアさんが出しているらしいのですが、Mac の M1チップには対応していないらしく今回はオンラインツールを使いました。
まずはgifから動画に変換し、動画からアニメWebP生成に変換。
※ gatsbyImage で圧縮すると、アニメーションがなくなってしまったので直起きしました。
<figure>
<img
src="***.WebP"
width="468"
height="136"
alt="***"
decoding="async"
loading="lazy"
/>
</figure>
WebPアニメーションは FireFox、Chrome、Safari でも動くし、このブログに関してはユーザーはほぼPCなので問題なし。
追記
以前タイムラプスを作るために ffmpeg を Homebrew 経由でインストールしたことがあったのを思い出し、コマンドですべて処理することにしました。
ffmpeg -i ***.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" ***.mp4
ffmpeg -i ***.mp4 -vf fps=5 -c:v libwebp -loop 0 -lossless 0 -quality 75 -preset 5 -an -vsync 0 ***.webp
これでかなり時短ができるようになりました。また機会があれば記事にまとめます。
picture タグを使ってユーザーの環境に応じて画像を出し分ける
このWebサイトは GatsbyImage で画像出力しているので基本は WebP で軽量化された状態で出力されます。
しかも、srcset などでユーザーの環境&ディバイスに応じて出し分けされています。
画像のサイズがある程度大きな場合に重宝します。
<picture>
<source type="image/WebP"
srcset="***.WebP 50w,***.WebP 100w,***.WebP 200w,***.WebP 400w"
sizes="(min-width: 200px) 200px, 100vw">
<img width="200" height="200" data-main-image=""
sizes="(min-width: 200px) 200px, 100vw"
decoding="async" src="***.jpg"
rcset="***.jpg 50w,***.jpg 100w,***.jpg 200w,/***.jpg 400w"
alt="***" style="object-fit: cover; opacity: 1;">
</picture>
WordPress でも picture タグを使った画像フォーマットやサイズの出し分けができます。WebPも対応する場合はプラグインなどを使うといいと思います。
DOMの整理
過剰なHTMLタグの数やネスト(入れ子)の深さは 過大な DOM サイズ となり、レンダリングに悪影響を及ぼします。
ページは表示されたのにローディング状態が続きボタンがクリックできない等 FID(First Input Delay)などにも悪影響を及ぼします。
各項目がこちらの表以上の数になると、PageSpeed Insight で警告が出ます。
項目 | 数 |
---|---|
DOMの最大深さ | 32 以上 |
子要素の上限数 | 60 以上 |
合計DOM要素数 | 1,500 以上 |
チェックポイント
- タグ のネスト(入れ子)を浅くする
- タグ数を減らす
このサイトは最大200近くタグが使われていることがわかりました。