Web 画像最適化の決定版 - WebP / AVIF / JPEG XL を実務でどう選ぶか
執筆: ありがっさまりょうた
デジタル道具屋を個人で開発・運用しています。記事は実装時の検証結果と公式仕様を照合して執筆しています。
本記事の執筆方針と編集ポリシーについてはAbout ページをご覧ください。
導入:PageSpeed のスコアを下げる最大の要因は画像
JavaScript や CSS を削減しても PageSpeed Insights のスコアが改善しない場合、原因の多くは画像にあります。 典型的な例として、トップページのヒーロー画像が 2.4 MB の JPEG で、しかも実際の表示サイズの 4 倍の解像度を持っている、 というケースが挙げられます。開発者ツールの Network タブで転送サイズの大きいリソースを並べ替えると、 この種の画像はすぐに見つかります。
Core Web Vitals の指標のひとつである LCP(Largest Contentful Paint)は、ビューポート内で最も大きい要素の描画完了時刻を測るため、 多くのページではヒーロー画像の読み込み時間がそのまま LCP になります。 同じ見た目のまま画像の容量を 1/5 程度に減らせれば、LCP は大きく改善します。 本記事では、フォーマット選定、品質設定、配信方法の順に、そのための具体的な手順を説明します。
1. 画像フォーマット早見表
| フォーマット | 圧縮効率 | 透過 | 使いどころ |
|---|---|---|---|
| JPEG | 標準 | × | 写真。互換性が最も高い |
| PNG | 可逆圧縮(容量は大きめ) | ○ | スクリーンショット、ロゴ、アイコン |
| WebP | JPEG 比でおおむね 25〜35% 小さい | ○ | 汎用。主要ブラウザで対応済み |
| AVIF | JPEG 比でおおむね 50% 前後小さい(画像により変動) | ○ | 写真。最も高効率だが Safari の対応は比較的新しい |
| SVG | ベクター | ○ | アイコン、ロゴ、グラフ |
あらゆる用途で最適な単一のフォーマットは存在しません。 写真か図版か、対象ブラウザの範囲、透過の要否、後から編集する頻度といった条件のトレードオフで選ぶことになります。 圧縮率の数値は画像の内容によって大きく変わるため、上記はあくまで目安として扱ってください。
2. 圧縮品質をどこまで下げてよいか
JPEG・WebP は 0〜100 で品質を指定します。用途別によく使われる目安は次のとおりです。
- 写真ヒーロー画像:JPEG 80 / WebP 75 / AVIF 60。視覚的にほぼ劣化なし
- サムネイル・リスト:JPEG 70 / WebP 65 / AVIF 50。容量重視
- ロゴ・スクリーンショット:PNG 8(256 色)または SVG。JPEG 系で文字を圧縮するとモスキートノイズが出る
- イラスト・フラットデザイン:WebP(lossless)または PNG
品質 90 以上は「サイズの割に画質はほぼ変わらない」領域に入りがちです。 逆に 60 を切るとブロックノイズが目立ちます。75〜80 を起点に、対象画像で目視確認するのが一番確実です。
3. picture / srcset でブラウザにフォーマットを選ばせる
AVIF を採用したい一方で、古いバージョンの Safari など未対応ブラウザでも画像を表示させる必要がある場合は、<picture> 要素でフォールバックを記述します。 ブラウザは <source> を上から順に評価し、type 属性の MIME タイプに対応していれば その候補を採用し、どれにも対応していなければ最後の <img> を使います。 したがって、AVIF → WebP → JPEG の順に並べれば、対応状況に応じて最も効率の良いフォーマットが自動的に選ばれます。
<picture>
<source srcset="hero.avif" type="image/avif" />
<source srcset="hero.webp" type="image/webp" />
<img
src="hero.jpg"
alt="ヒーロー画像"
width="1200"
height="630"
fetchpriority="high"
decoding="async"
/>
</picture>width と height は 必ず指定してください。 未指定だと、画像読み込み中にレイアウトが崩れて CLS(Cumulative Layout Shift)が悪化します。 実際の表示サイズは CSS で制御して構いません。属性値はアスペクト比の計算にのみ使われるため、 元画像の縦横比と一致していれば十分です。 ヒーロー画像には fetchpriority="high" を付けて先読みを優先し、 ファーストビュー外の画像には loading="lazy" を付けて遅延読み込みにするのが基本です。 LCP 要素に loading="lazy" を付けると読み込み開始が遅れ、かえって LCP が悪化する点に注意してください。
4. 実装前にやること
a. 元画像の解像度を見直す
スマートフォン表示で 400px 幅にしか映らない画像が、元データでは 4000px あるケースは珍しくありません。表示の最大サイズ × 2 倍(Retina 用)を上限と考え、それ以上はリサイズしてから配信します。
画面幅によって表示サイズが変わる画像には、srcset と sizes で複数の解像度を用意し、 ブラウザに適切なものを選ばせます。次の例では、ビューポート幅が 640px 以下なら画面幅いっぱい、 それ以外は最大 800px で表示される前提で、3 種類の幅の画像を提供しています。
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
sizes="(max-width: 640px) 100vw, 800px"
alt="商品写真"
width="800"
height="600"
loading="lazy"
decoding="async"
/>srcset の w 記述子には各ファイルの実際のピクセル幅を書きます。 ブラウザは sizes から求めた表示幅とデバイスピクセル比を掛け合わせ、 必要な解像度を満たす最小のファイルを選択します。 これにより、幅 400px の端末に 1600px の画像を送るような無駄を防げます。
b. PNG はまず WebP に変換できないか検討する
スクリーンショットや UI モックアップは、PNG のままだと数 MB に膨れがちです。 WebP の lossless モードで圧縮すると、画質を完全に維持したまま容量を削減できます。 削減率は画像の内容に依存しますが、単色の領域が多い UI 画像ではおおむね 30〜50% 程度小さくなることが多く、 透過も保持されるため PNG からの置き換え候補として検討する価値があります。
5. ブラウザで完結する圧縮ツール
サーバーにアップロードせずに圧縮したい場合は、当サイトの画像圧縮ツールが利用できます。 ファイルはブラウザ内で処理され、外部サーバーへ送信されません。 顧客情報を含むスクリーンショットや、未公開の画像素材を扱う場合に適しています。
関連: 画像切り抜き、SNS 画像リサイザー、アイコンリサイザー。
よくある失敗パターン
CMS やエディタの「クリーンアップ」機能が img タグの width / height 属性を削除してしまい、 それまで問題のなかったページの CLS が悪化して Core Web Vitals の判定が「不良」になる、というパターンがあります。 HTML を自動整形する仕組みを導入している場合は、リリース前に Lighthouse または PageSpeed Insights で CLS の値と「画像要素に width と height が明示されていない」という診断項目を確認してください。
参考にした一次情報
本記事の内容は、以下の公式仕様や一次情報を参照して執筆しています。
- Image formats — web.dev
Google web.dev
https://web.dev/learn/images/
- WebP - A new image format for the Web
Google Developers
https://developers.google.com/speed/webp
- AVIF for Next-Generation Image Coding
Alliance for Open Media
https://aomediacodec.github.io/av1-avif/
- Largest Contentful Paint (LCP) - web.dev
Google web.dev
https://web.dev/articles/lcp
この記事の内容を実際に試す
解説した内容は、以下のツールでブラウザ上から無料で試せます。