新人にもわかる!WebPのブラウザ振り分けの仕組みを図解。picture要素と.htaccessのどっちでやるべき?
新社会人のみなさんが初出社を迎えた会社も多いでしょう。
今日はWebP対応/非対応ブラウザに向けた適切な振り分けについて、新人さん(...が今WebPなどを使うかどうかは置いといて...)にもわかりやすく解説します。
過渡期のWebPはブラウザ振り分けが必須
2019年4月現在、WebPに非対応のブラウザもまだまだ多いので、WebPを使う場合はブラウザの種類やバージョンによる振り分けが必要です。
つまり、ひとつの画像について、WebPに対応したブラウザでは軽いWebPフォーマットで、対応していないブラウザでは従来のJpegやPNGフォーマットで表示する仕組みを用意しなければなりません。
振り分けの方法には、ブラウザ側(HTML)で行う方法と、Webサーバー側で行う方法があります。
いきなり結論「理由がなければWebサーバーで振り分けをおすすめ」
Webサーバー上で振り分けしましょう。その方が安全で楽ちんです。むしろHTMLでの振り分けは(手作業では)かなり無理ゲーだと思います。
(1) ブラウザ上(HTML)での振り分け
HTMLでは次のようにpicture要素、source要素で「ひとつの画像について選べるふたつのフォーマット」を指定します。 元の画像がsample.png、そのWebP版がsample.png.webpです。
<picture>
<source type="image/webp" srcset="sample.png.webp" />
<img src="sample.png" />
</picture>
WebPに対応したブラウザは、「sample.pngではなくもっと軽いsample.png.webpがあるんだな。ではそれを使おう」と判断します。
一方、非対応のブラウザはimage/webpを知らないので、最後の手段であるimg要素が指すsample.pngを表示します。
図に表すと次の通りです。
拡張子がふたつ続いても大丈夫なの?
sample.png.webpという名称が気になった方がいるかもしれません。この記法は確かに珍しいものではありますが、利用上はまったく問題ありません。
なぜsample.pngでないの?
sample.pngのWebP版をsample.webpとして記述する例も見かけます。しかし私はsample.png.webpとオリジナル画像の拡張子に更に追加.webpを重ねることをおすすめします。
なぜなら将来もしWebPが主流になったときには、オリジナル画像をWebPとして作ることになるでしょう。
そのとき、次のように区別が付きやすくなります。
- sample.png.webpはsample.pngを元に作られたコピーのWebPファイル
- sample.webpは元々WebPとして作られた画像ファイル
もう一点、Webサーバー上で振り分け設定を行う場合にも拡張子を重ねた方が記述がスッキリする利点があります。
(2) Webサーバー上での振り分け
ブラウザは、サーバーにデータをリクエストするとき、ユーザーには見えないリクエストヘッダーという情報を付加しています。
有名なのはUser-Agentです。ブラウザやOS、バージョンごとに固有な情報となっているので、ユーザーの環境を判断するためによく用いられます。
- 例(macOSのChrome): Mozilla/5.0 (Macintosh; Intel Mac OS X 10144) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
このUser-Agentと同様にAcceptというリクエストヘッダーも、裏でブラウザからサーバーに渡されています。
Acceptは、対応するデータフォーマットをサーバーに知らせる役割を持ちます。これがWebP対応ブラウザを判定する鍵となります。
- 例(WebP非対応のmacOSのSafari): text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
- 例(WebP対応のmacOSのChrome): text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3
WebPに対応するChromeには、image/webpというテキストが含まれることにお気づきでしょうか?
現在、WebPに対応するブラウザは、このようにAcceptヘッダでそれを自己申告する慣習になっています(Microsoft Edgeは現在のところ例外...)。
なので、sample.pngというファイルを要求されたとき、相手がWebP対応ブラウザであればこっそりその中身をWebPに差し替えてしまえばよいのです。
これを図にすると次の通りです。
拡張子.pngでWebPを返していいの?
これも気持ち悪いかもしれませんが、実際はまったく支障ありません。
Webサーバーは、これもユーザーの目に見えないHTTPレスポンスヘッダーを使ってそのファイルがどんなファイルフォーマットになっているか返しています(Content-Type)。
- 例(データがJpegファイルである場合): Content-Type: image/jpeg
しかし実際のところは、画像データはこのContent-Typeも無視して実際のファイルのフォーマットで判断されます。
拡張子、Content-Type、実際のデータフォーマットが「ちぐはぐ」でもブラウザはちゃんと表示します。これについては実際に検証した結果があります。
具体的にはどのように設定するのか
Apacheであれば.htaccessファイルで簡単にできます。実質7行です。nginxはもっと簡単です。
具体的な方法はここでは割愛します。次の記事を参考ください。
- WebPと従来の画像を正しく振り分ける.htaccessファイル
- ページの画像をまるごとWebP変換してPageSpeed Insightsスコアを今すぐ改善するチュートリアル
- .htaccessによるWebPの選択的レスポンスとその問題点と改善案
- nginxにおけるWebP画像の選択的レスポンスの設定方法
- CloudFrontにおけるWebPの選択的レスポンス
結局どっちがいいの?
冒頭で結論を述べましたが、多くのWeb制作の現場にとっては、Webサーバー側での振り分けが現実的です。
タスクランナーやアセットパイプラインをしっかり導入・運用できているような技術的に高度なチームでなければ、ブラウザ側(HTML)での対応はおすすめしません。
手軽さは?
確かにブラウザ側(HTML)での振り分けは手軽です。Webサーバー側の設定変更は慣れた人でなければ少し気後れするでしょう。
作業量は?
ブラウザ側(HTML)での振り分けは、WebP対応する画像についてひとつずつ、picture要素に置き換える必要があります。これは数が多いと大変で、間違いも出やすくなります。
一方、Webサーバー側での振り分けは、ほとんどの場合、一箇所の修正のみで完了します。全体としては圧倒的に手間が少ないと言えます。
表現力は?
WebP対応という点についてはどちらも同じですが、ブラウザ側(HTML)での振り分け方法は、高解像度Retinaディスプレイへの最適化やアートディレクションにも拡張できます。
picture要素、source要素は手軽であると同時に、玄人向けのアプローチです。
CSS背景は?
HTMLでimg要素が参照する画像を振り分ける方法はありますが、CSSで背景画像などとして参照する画像を振り分ける合理的な方法は現在のところありません。
Webサーバー側での振り分けであれば、img要素だろうと背景画像だろうと、WebPを適切に振り分けます。
安全性
ブラウザ上(HTML)での振り分けにおいて、もしWebP版ファイルsample.png.webpが存在しなかったらどうなるでしょうか?
<picture>
<source type="image/webp" srcset="sample.png.webp" />
<img src="sample.png" />
</picture>
存在しない場合は代わりにsample.pngを読み込んで欲しいところですが、あいにく画像のリンク切れとなってしまいます(Chrome、Firefoxで確認)。
Webサーバー側での振り分けであれば、sample.png.webpというファイルがない場合はsample.pngを返すことができるので画像リンク切れにはなりません。万が一に備えたフォールバックが機能するので安全です。
以上です。
WebP対応において、ファイル変換処理と同じくらい大事な振り分け処理。判断基準のひとつになれば幸いです。
メール無料相談
お聞きになりたいことはありませんか? この記事の筆者 代表取締役 宮永 がまずはメールで疑問やお悩みを伺います! フォームよりお気軽にお寄せください。
フォローしませんか?