速くする
画像、読み込みを止めるもの、JavaScript の量。この順に手を入れると、たいていの遅さは解けます。
図の中身を文字で読む
- 効く順に手を入れる。上から3つで、たいていの遅さは解ける。
- 1 画像 ページ全体の重さの過半を占めることが多い
- 表示する寸法の2倍を超えないところまで縮める(横1200pxの枠に4000pxを置かない)
- AVIF か WebP を第一候補にする。写真は JPEG より小さくなる
- srcset で画面幅ごとの候補を渡す。最初の画面より下は loading="lazy"
- 最初の画面に映る画像だけは lazy にしない。fetchpriority="high" を付ける
- 2 読み込みを止めるもの head の中の CSS と同期 script は、表示を待たせる
- script には defer を付ける。head で同期実行しない
- Webフォントは font-display: swap と preload。読めない時間を作らない
- 3 JavaScriptの量 転送量より、解析と実行の時間が効く
- その画面で要らないものを送らない。使う場面まで読み込みを遅らせる
- サーバーの応答(TTFB)と配信の距離は、上の3つを終えてから見る。静的サイト生成やキャッシュはここに効く。
- 計測せずに手を入れない。何が重いかは、開いてみるまで分からない。
ひと目で#
画像 → 読み込みを止めるもの → JavaScript の量。 この順で手を入れると、たいていの遅さは解けます。
- 画像フォーマット
- AVIF と WebP を第一候補に。写真は JPEG より小さくなる
- srcset
- 画面幅ごとの候補を渡し、ブラウザに選ばせる
- 遅延読み込み
- 最初の画面より下の画像だけ
loading="lazy" - レンダリングブロック
- head の CSS と同期の script は、表示を待たせる
- クリティカルCSS
- 最初の画面に要る分だけ先に届ける
- 静的サイト生成
- ビルド時に HTML を作る。応答が速い
- プログレッシブエンハンスメント
- HTML だけで成り立たせ、その上に足していく
効く順#
| 順 | やること | 効く指標 |
|---|---|---|
| 1 | 画像を表示寸法の2倍以下に縮める | LCP |
| 2 | AVIF / WebP にする。srcset を渡す | LCP |
| 3 | 最初の画面の画像は fetchpriority="high"、それ以外は lazy | LCP |
| 4 | script に defer。Webフォントは preload と font-display: swap | LCP |
| 5 | 画像、動画、広告枠に width / height を書く | CLS |
| 6 | その画面で使わない JavaScript を送らない | INP |
| 7 | 静的生成、キャッシュ、配信の距離 | TTFB |
遅らせてよい画像、いけない画像#
loading="lazy" は近づくまで取りに行かない指示です。最初の画面に映る主役の画像にこれを付けると、HTML を読み終えるまで取りに行かず、LCP がそのぶん遅れます。
図の中身を文字で読む
- ✕ 画像を全部 lazy にする ○ 最初の画面だけ先に読む 届く順番
- ✕ 全部 lazy
- HTML
- HTMLを読み終えてから主役を探し始める
- 最初の画面の底
- ○ 主役だけ先に
- HTML
- 解析と並行して主役が届く
- 主役の画像にも lazy が付いている 上は fetchpriority="high" 「最初の画面」は端末で変わる。
- HTMLを読み終えるまで取りに行かず、 下だけ loading="lazy" 狭い画面ほど、上に入る画像は少ない。
- LCP がそのぶん遅れる 主役が先に届き、下は近づいてから取りに行く 迷ったら先頭の1枚だけを高優先にする。
境目は「最初の画面に映るか」です。映るものは fetchpriority="high" で先に取りに行かせ、それより下だけ lazy にします。狭い画面ほど最初の画面に入る画像は少ないので、迷ったら先頭の1枚だけを高優先にします。
間違えやすいところ#
- 測らずに手を入れる何が重いかは、開いてみるまで分からない
- 全部の画像を
loading="lazy"にする最初の画面の画像まで遅れ、LCP が悪くなる - 原寸のまま
widthで縮める転送量は変わらない - Webフォントを何書体も読み込む1書体でも数百KB。字形のサブセットを考える
font-display: blockのまま放置する文字が読めない時間ができる- 画面ごとに分けずに1つに束ねる使わないコードの解析時間を、全員が払う
- JavaScript が動かないと何も出ない構造にする失敗したときに白紙になる
対策を確かめる#
本文の「効く順」を、手を入れたか確かめる形にしました。各項目に、そのまま貼れる1行を添えています。チェックはこの端末に残ります。
JavaScript が無効でもチェックは付けられますが、記録はこの端末に残りません。
実装#
このコードで動いている見本です
直す例#
架空の案件を1つ例にとります。どこを見て、何をどう直すかを書きます。
工房の通販ページです。商品写真24枚に loading="lazy" が一括で付いています。良かれと思った指定ですが、最初の画面に映る1枚目まで後回しになり、LCP がそのぶん遅れています。
境目は「最初の画面に映るか」です。先頭の1枚だけ fetchpriority="high" にし、lazy は外します。残り23枚はそのままで構いません。
同じページで、写真は 3000px の JPEG が原寸で置かれ、width で表示だけ縮めてありました。転送量は縮んでいません。表示寸法の2倍を上限に書き出し、AVIF と WebP を用意して srcset で選ばせます。24枚のうち、最初に届く必要があるのは1枚だけです。
確認する#
- 最初の画面に映る画像が
lazyになっていない(かつ高優先が付いている) - 配信している画像の実寸が、表示寸法の2倍以下に収まっている
- ネットワークの記録で、最初の画面に要らないファイルが先に届いていない
使えるパターン#
このページで扱う語#
このページで扱う語を並べる本文では太字4 語
語の名前から引くなら用語索引へ。
- バンドルサイズ
- 配信される JavaScript の総量。大きいほど読み込みと実行の時間が増える。
- ハイドレーション
- サーバーで生成された HTML に、ブラウザ側で JavaScript の機能を結び付けて操作可能にする処理。
- デバイスピクセル比
- 物理的な画素と CSS ピクセルの比率。2倍なら、1 CSS ピクセルが 2×2 の物理画素で描かれる。
- グレースフルデグラデーション
- 最新環境向けに作ったうえで、機能が使えない環境でも破綻せず段階的に品質を落とす設計方針。
この話が要る場面#
このページが答えになる、現場の困り事です。困り事の側から探すと、同じ場所に着きます。
画像から。表示寸法の2倍以下に縮め、AVIFかWebPにし、最初の画面より下は lazy にする。
このコードで動いている見本です
画像、読み込みを止めるもの、JavaScriptの量の順。上から3つでたいていの遅さは解ける。
1. 画像をAVIF/WebPに
2. script に defer
3. 使わないJSを送らないhead の同期scriptとCSSが表示を待たせている。script に defer を付ける。
このコードで動いている見本です
写真はAVIFかWebP、図はSVG。透過が要るPNGは、AVIFで置き換えられることが多い。
このコードで動いている見本です
幅の候補を w で並べ、sizes に表示幅を書く。sizes を省くと100vwとみなされ、大きすぎる画像が選ばれる。
このコードで動いている見本です
キャッシュが残っている。ファイル名かクエリを変えて配信する。
このコードで動いている見本です
この場面のほかの困り事と、そのまま貼れる部品は速くする、出す前と出したあとにまとめてある。逆引きには全188件。