画像フォーマットの出し分け戦略|ブラウザ対応と品質のバランスを取る実践法

C
クリオ
Web制作ディレクター / フロントエンジニア

こんにちは!

今日は「画像フォーマットの出し分け戦略」について解説します。
これめっちゃ重要なテーマやねん。

「最新だからWebPにしよう」は危険な考え方

僕も現場に入った初期の頃、めっちゃ失敗した経験があります。
「WebPは圧縮率が高いしモダンだ」という理由だけで、すべての画像をWebPに統一しようとしたんですよ。
そしたら案の定、古いブラウザで表示されんくなって、クライアントから苦情が来ました……。

WebPは確かに優秀なフォーマットです。
同じ品質なら、JPEGやPNGと比べて20~30%ファイルサイズを削減できます。
でもね、これが全部のブラウザで対応してるわけじゃないんですよ。

特に以下のシーンでは要注意です:

  • 企業のコーポレートサイト(年配のユーザーが多い)
  • BtoB系サービス(Internet Explorer 11をまだ使ってる企業がある)
  • アクセス解析を見たら古いOSユーザーが一定数いる

つまり、「対応状況を確認してから判断する」が正解なんです。
WebP単体で統一するのではなく、「WebPを使いつつ、対応していないブラウザには別のフォーマットを出す」という考え方が大切ですよ。

picture要素を使った正しい出し分け方法

では、実際にどうやって出し分けるのか。
ここで活躍するのが<picture>要素です。

基本的な書き方はこんな感じです:

<picture>
  <source srcset="/images/photo.webp" type="image/webp">
  <img src="/images/photo.jpg" alt="説明文">
</picture>

これだけです。
超シンプルですが、ほんま強力なんですよ。

処理の流れはこうなります:

  1. ブラウザが最初の<source>を見る
  2. WebPに対応してたら、そっちを読み込む
  3. 対応してなかったら、<img>のJPEGを読み込む

古いブラウザでもちゃんと画像が表示されるし、新しいブラウザなら軽いWebPが読み込まれる。
これが「出し分け」の基本形ですね。

でもね、実務ではもうちょっと複雑なことがよくあります。
レスポンシブ対応で、サイズごとに違う画像を出したいときとか。

そういう時はこんな感じでいけます:

<picture>
  <source 
    media="(max-width: 767px)" 
    srcset="/images/photo-mobile.webp" 
    type="image/webp">
  <source 
    media="(max-width: 767px)" 
    srcset="/images/photo-mobile.jpg">
  <source 
    srcset="/images/photo-desktop.webp" 
    type="image/webp">
  <img src="/images/photo-desktop.jpg" alt="説明文">
</picture>

スマホサイズではモバイル向けの画像、デスクトップサイズではデスクトップ向けの画像を出す。
その上で、各サイズごとにWebPとJPEGを出し分けるというわけです。
これめっちゃ効果的やねん。

ちなみに、srcsetの順序は大事です。
上から順番に「このメディアクエリに合ってるかな?」って判定していくので、モバイルを先に書くときは必ずメディアクエリをつけてくださいね。

実務で起きやすいトラブルと対策

実際の案件でよく見かけるのが、以下のような失敗です。

トラブル1:WebP化ツールを導入したら、すべて一括変換されてしまった

これね、よくあるんですよ。
「自動化ツール入れたら楽になるや」って思って導入したら、確認なしに全部WebPに変わっちゃった。
で、古いブラウザで壊れてる、みたいな。

解決策としては、ツール設定で「picture要素を使った出し分けHTMLを自動生成する」オプションをオンにすることです。
TinyPNGやImageOptimなんかのツールでも、このオプション用意されてることが多いですよ。

あるいは、自分たちでスクリプト組んで、元画像とWebP版を並行管理する方が安全なこともあります。

トラブル2:WebP化したら、ファイルサイズが逆に大きくなった

これは「圧縮品質の設定ミス」が原因なことがほとんどです。
WebPも品質レベルを指定しないと、デフォルトでめっちゃ高品質になるんですよ。
だからファイルサイズが増えちゃう。

通常はJPEGの品質を85くらいに設定するように、WebPでも品質をquality=80とかquality=75に落とすといいですよ。
どの程度で見た目が劣化しないかは、プロジェクトごとに調整が必要です。

トラブル3:複数の古いフォーマットもサポートしたい

稀ですが、GIFアニメーションとか、AVIF(さらに新しいフォーマット)とか、複数フォーマットに対応したいときもありますよね。

そういう時は、こんな感じで<source>を連ねればOKです:

<picture>
  <source srcset="/images/photo.avif" type="image/avif">
  <source srcset="/images/photo.webp" type="image/webp">
  <img src="/images/photo.jpg" alt="説明文">
</picture>

ブラウザが対応してる順番に読み込んでくれるので、このAVIF→WebP→JPEGという順序がベストプラクティスとされてますよ。

まとめ

画像フォーマットの出し分けって、最初は「複雑だな……」って感じるかもしれません。
でも、<picture>要素を使えば、シンプルに解決できるんですよ。

大事なポイントをまとめると:

  • WebPは優秀だけど、すべてのブラウザ対応じゃない