コメントを投稿するにはログインが必要です
ログインページへ
八百万のOSSWebサービスで画像をきれいに、軽く配るには何から考えればよいのでしょうか。今回は、可逆圧縮で透過も扱えるPNGと、非可逆圧縮で写真に向くJPEGの違いを出発点に、画像フォーマットの選び方と、それを実際のサービスで運用するための設計を整理します。
現代のスマートフォンはカメラの性能が高く、Webサービスでそのまま扱うには大きすぎる画像がアップロードされることがあります。Canvas APIを使えば、ブラウザ上で画像を変換できます。ただし、必要な画質や保存したい元画像、通信量、変換を行う場所はサービスによって異なります。画像を一律に小さくすればよいのではなく、そのサービスに合った扱いを決める必要があります。
配信する画像では、細かなquality設定より先に十分な画像サイズを確保します。高密度ディスプレイではCSS上の表示幅より大きな画像が必要ですが、全員に最大サイズを送ると転送量が増えます。そこで、固定サイズのサムネイルを事前生成する構成から、必要な派生画像を動的に生成してCDNへキャッシュする構成へ。`Accept`ヘッダーによるフォーマットの出し分けと、`picture`・`srcset`で複数サイズからブラウザに選ばせる方法を紹介します。
WebPは写真に有効な一方、テキスト画像やドット絵まで機械的にWebPへ変換するのは現実的ではありません。WebPの実装が実質的にlibwebp一つに限られていることや、画像の種類に応じたpresetの扱いも取り上げます。現在ではAVIFも有力な選択肢で、JPEGをフォールバックにしてAVIFを追加する構成も考えられますが、AVIFはエンコード負荷が高い点に注意が必要です。どの形式でも同じqualityの値が同じ見た目を意味するわけではないため、実際の画像と容量を見ながら調整します。
ImageMagickやcwebpを使えば、サーバー側でも画像を変換できます。ただし、変換処理が一度成功することと、ユーザーがアップロードする多様な画像を継続して処理できることは別です。極端な縦横比や想定外の画像が来たときの処理負荷、変換後のファイルサイズなど、実サービスで確認すべき点にも踏み込みます。
画像URLをフロントエンドで自由に組み立てず、バックエンドが許可済みの候補URLを返す理由も、後方互換性とCDNキャッシュ効率の両面から考えます。派生画像をCDNへキャッシュし、実際に配信されたオブジェクトサイズを監視する。必要に応じて画像変換SaaSへ任せる。WebPを選べば終わりではなく、入力、変換、URL、キャッシュ、監視をどのようにつなげるかまで、実際の運用を想像しながら考える回です。
- catatsuy「CDNを活用した画像配信の設計と最適化」: https://zenn.dev/catatsuy/articles/43b5cf583fac76
- catatsuy「サムネイル画像URLはバックエンドで生成すべき」: https://zenn.dev/catatsuy/articles/4070de849114e0
- catatsuy「CDNを活用して高速なWebサービスを提供する」: https://zenn.dev/catatsuy/articles/ea86bdba548ab9
- catatsuy「Webサービス上の画像変換とWebPの利用について」: https://engineering.mercari.com/blog/entry/20201211-image-optim-webp/
- ImageMagick: https://imagemagick.org/
- WebP: https://developers.google.com/speed/webp
- libwebp: https://chromium.googlesource.com/webm/libwebp
- libavif: https://github.com/AOMediaCodec/libavif
- Squoosh: https://squoosh.app/
- Fastly Image Optimizer: https://www.fastly.com/products/image-optimizer
- picture要素(MDN): https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/picture
- レスポンシブ画像(MDN): https://developer.mozilla.org/ja/docs/Web/HTML/Guides/Responsive_images
- Acceptヘッダー(MDN): https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Headers/Accept
- Canvas API(MDN): https://developer.mozilla.org/ja/docs/Web/API/Canvas_API
─────────────
YouTube: https://youtu.be/7Qlmj-X1yhU
Web: https://yaoyorozu-oss.henteko07.com/
X: https://x.com/yaoyorozu_oss