はじめに
さくらのウェブアクセラレータに限らない話ですがCDNやウェブサーバーで画像を配信するとき、WebP 対応ブラウザには WebP 画像、非対応ブラウザには PNG 画像と出し分けをしたいケースがあります。また Retina ディスプレイのような高解像度のデバイスには高解像度の画像を配信したいというケースもあるでしょう。
HTML の picture タグを使った画像の出し分け
さくらのウェブアクセラレータ(CDN) は Varyサポート機能 により1つのURLで最大5種類のコンテンツをキャッシュして出し分けることができますが、画像の出し分けには HTML の <picture>
タグを使うほうがお勧めです。
例えばWebPとPNGを表示可能なブラウザに応じて出し分けたい場合、 Vary: Accept
と指定すれば出し分け自体は可能ではあるのですが、 既定の Accept 値の一覧 - HTTP | MDN にあるようにブラウザの種類やバージョンによって Accept ヘッダの値がまちまちなため、上記の5種類を超えてしまい古いキャッシュが上書きされてしまいキャッシュヒット率が上がらないという問題が起きてしまいます。
Vary ではなく <picture>
タグを使うと画像ごとにURLが別になりますのでこの問題を回避できます。
また、画像変換・配信エンジンImageFlux|さくらインターネット で Vary ヘッダを使う場合も1つのURLでキャッシュ可能なコンテンツは最大5種類ですので、同様に <picture>
タグの活用をご検討いただくと良いと思います。
<picture>
タグについては Mozilla Developer Network の下記のページの説明がわかりやすいと思います。<picture>: 画像要素 - HTML: HyperText Markup Language | MDN
<picture>
タグの仕様は HTML Standard - 4.8.1 The picture element (日本語訳) で確認できます。
picture タグでの画像の出し分け例
例えば以下のような HTML を作成します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>picture tag example</title>
</head>
<body>
<picture>
<source srcset="logo-2x.webp 2x, logo.webp" type="image/webp"/>
<source srcset="logo-2x.png 2x" type="image/png"/>
<img src="logo.png" alt="logo"/>
</picture>
</body>
</html>
<source>
タグに type="image/webp"
属性を指定することで WebP 対応ブラウザであれば WebP の画像を取得して表示します。さらに srcset
属性内でファイル名の後に 2x
と書くと高解像度の画面の端末であればその画像を取得して表示します。また <picture>
タグに非対応の Ineternet Explorer でも <picture>
の子要素に置いた <img>
タグを解釈して画像を表示してくれるので、画像が表示されないということはありません。
サンプルの画像は ImageMagick をインストールした環境で以下のコマンドで作成できます。表示したときにどの画像かがわかるように左下に文字を入れています。
convert logo: -gravity SouthWest -pointsize 30 -annotate +0+10 'png' logo.png
convert logo: -gravity SouthWest -pointsize 30 -annotate +0+10 'png 2x' \
-resample 144 logo-2x.png
convert logo: -gravity SouthWest -pointsize 30 -annotate +0+10 'webp' logo.webp
convert logo: -gravity SouthWest -pointsize 30 -annotate +0+10 'webp 2x' \
-resample 144 logo-2x.webp
上記のHTMLと画像をウェブサーバーに配置してアクセスしてみると以下のように閲覧環境ごとに異なる画像を配信できることを確認できました。
- Mac-mini macOS 11.6 の Chrome 97 と Safari 16.0 では logo-2x.webp
- FullHDディスプレイの Windows 10 の Chrome 97 では logo.webp
- 古い iPad Air (iOS 12.5.5) のSafari では logo-2x.png
- FullHDディスプレイの Windows 10 の Internet Explorer 11 では logo.png
おわりに
<picture>
タグを使うとさくらのウェブアクセラレータでも簡単に画像の出し分けが出来ますので、ぜひご活用ください!