JPEG/PNG/GIFの画像をWebPなどの次世代画像フォーマットに変換して配信するとき、変換をいつ実行するかで設計が分かれる。大きくは、配信を始める前にまとめて変換する事前変換と、リクエストを受けてから変換する都度変換の2つだ。
どちらにも一長一短がある。弊社のLightFile Proxyでは、両者のデメリットを打ち消す半同期変換を採用している。順に詳しくみていきたい。
連載「詳説 LightFile Proxy」
AWS CloudFrontの後ろに置いて、既存のサイトを変えずに画像をWebPで配信する仕組みを説明する連載。
- サイトに手を加えず画像をWebPで配信する仕組み
- 拡張子は.jpgのまま中身をWebPにしてよいのか
- 画像変換のタイミングとその最適解(本記事)
- 次世代画像フォーマットの採用でどのくらい画像が軽くなるか(9月28日公開予定)
- WebP化によるデータ削減で見た目は劣化するか(9月29日公開予定)
- 画像のリンク切れを起こさない二重の障害対応(9月30日公開予定)
- 無駄な変換を避け高速に画像を配信するためのキャッシュ戦略(10月1日公開予定)
- その他の細かな特徴(10月2日公開予定)
- AWS純正のDITで代替できるか(10月3日公開予定)
- 料金体系(10月4日公開予定)
事前変換 配信前にまとめて変換
最初に考えつくのは、配信を始める前に全部の画像を変換しておく方法だ。バッチで一括変換し、変換済みをキャッシュに並べておく。

配信の経路に変換が入らないので応答は安定して速い。画像の種類が少ないサイトなら、これで十分間に合う。
負担が出るのは画像が多いサイトだ。ECサイトでは商品1点につき複数枚の画像があり、点数が増えれば数万枚から数十万枚になる。ここで次の3つが問題になる。
- 全部を変換する手間。 初回の一括変換に時間がかかるうえ、日々追加される画像に追随する仕組みを別に用意することになる
- キャッシュの容量。 従来フォーマットとWebPの2セットを持ち続ける
- 使われない画像まで変換する。 販売が終わった商品の画像も、誰も開かないページの画像も、等しく変換されて容量を占める
変換済みをどこに置き、どう差し替えるかを決める時点でデータ作成の手順にも関わってくるので、既存のシステムに手を付けないという前提も保ちにくい。
都度変換 リクエストを受けてから変換
もう一方の都度変換は、リクエストが来た時点で変換する。素直に作ると、変換が終わるのを待ってから変換済みの画像を返す形になる。この作りを同期変換と呼ぶことにする。

必要になった画像だけを変換するので無駄がなく、初回から軽い画像が届く。事前変換の3つの負担は消える。
代わりに、変換にかかった時間がそのままエンドユーザーの待ち時間になる。変換した結果はキャッシュするので、2回目以降のエンドユーザーは待たない。問題は、その1回目がどれだけあるかだ。
ロングテールでは1回目の割合が高い
ECサイトのアクセスは、ページと画像のどちらもロングテールを描く。ごく一部の人気商品にアクセスが集中する一方、大多数の商品ページは何日かに一度しか開かれない。
商品数が多いサイトでは、この裾野に膨大な枚数の画像がある。1枚あたりのアクセスが少ないということは、全アクセスに占める「1回目」の割合が高いということでもある。同期変換ではその1回目がすべて変換待ちになり、待たされるのはたまたま最初に来たエンドユーザーだ。
アクセスが集中したときの負荷も同期変換の弱点になる。変換は計算資源を使うので、同時に来たリクエストの数だけ変換が走れば遅れが積み上がる。
半同期変換 オリジナルを返しながら変換
LightFile Proxyが採っているのは都度変換の一種で、事前変換と同期変換の短所を打ち消すように作ってある。リクエストを受けたら変換を始めるが、そのリクエストの応答は変換を待たない。1回目と2回目以降で動きが違うので、分けてみていきたい。
1回目 オリジナルを返して変換は積むだけ

- 変換済みのWebPがキャッシュにあるか探す(1回目なのでまだ無い)
- オリジンからオリジナル画像を取得する
- ひとまずオリジナル画像をそのまま返す(キャッシュ期間を短く設定)
- 画像を返してからバックグラウンドで変換する
同期変換との違いはここに出る。同期変換では変換にかかった時間がまるごとエンドユーザーの待ち時間になるが、半同期変換でエンドユーザーが待つのはオリジンから画像を取ってくる時間だけで、変換の待ち時間はゼロになる。
1回目のエンドユーザーに届くのはオリジナルなので、その1回だけはWebPにならない。
2回目以降 変換済みのWebPを返す

ここで効いてくるのが、1回目に付けた10秒という短いキャッシュ期間だ。CloudFront側のキャッシュがすぐ切れるので、CloudFrontは同じ画像をもう一度取りに来る。 その頃には裏で走っていた変換が終わっていて、キャッシュには変換済みのWebPがある。今度は長いキャッシュを付けて返すので、CloudFrontにWebPがキャッシュされる。
アクセスの多い画像ほど、この再アクセスは早くやってくる。よく見られている画像から順にWebPに入れ替わっていく形になる。
変換が混み合っているときは、短いキャッシュの期間を自動で延ばす。変換がまだ終わっていないのに何度も取りに来られると、同じ画像の変換が繰り返し呼ばれてしまうためだ。
エンドユーザーが待つ時間のモデル
ここまでの動きを、エンドユーザーが待つ時間の長さとして並べるとこうなる。

差が出るのは1回目だけになる。同期変換では、オリジナルを取ってくる時間に変換の時間が積み上がる。
半同期変換の1回目は、取ってきたオリジナルをそのまま返す。JPEGやPNGのままなのでデータは大きく、返すのに少し時間がかかるが、それでも変換を待つよりずっと短い。変換は応答の外で走る。
2回目以降はどちらも変わらない。 変換済みをキャッシュから読んで返すだけになる。
処理の総量が減るわけではない。変換という重い処理を、エンドユーザーを待たせる場所から外に出しているだけだ。中継が1段増えるのでそのぶんの往復はあるが、変換の時間が応答に乗らないので、同期変換より短い時間で返せる。
そしてロングテールでの振る舞いも同期変換と変わってくる。変換した結果はCDNのキャッシュとは別に持ち続けるので、めったにアクセスされない画像でも変換は最初の1回だけで済む。次にいつ来ても、そのエンドユーザーは変換済みを受け取る。事前変換のように使われない画像まで作ることもない。
ロングテールのアクセスに強い
商品数の多いECサイトでは、ページへのアクセスが極端に偏る。

トップページやランキングに出るページは繰り返し見られるので、キャッシュが効きやすい。一方、大多数の商品ページはたまにしか見られない。次に誰かが来るまでに間が空くので、そのアクセスの多くが「1回目」になる。
2回目以降はキャッシュが効いて速い、というのはそのとおりだ。ただし裾野では、その2回目以降のアクセスがそもそも少ない。同期変換では、多数を占める1回目がすべて変換待ちになる。速い2回目の恩恵を受ける人より、遅い1回目の犠牲になるエンドユーザーのほうが多い、という状態になりやすい。
半同期変換なら、その1回目でも変換を待たせない。裾野が広いサイトほど、この差が効いてくる。
半同期変換が妥協している点
半同期変換ももちろん万能ではない。
上で書いたとおり、1回目のエンドユーザーはWebPを受け取らない。画像を差し替えた直後も同じで、変換が終わるまでの数秒から数十秒はオリジナルが配信される。最初の1人に変換を待ってもらうか、最初の数秒はWebPにしないか、という選択で、LightFile Proxyは後者を選んでいる。
変換が追いつかない状態も見えにくい。大量の画像が一度に登録されて変換の待ち行列が伸びると、WebPで配信される割合が下がる。このときエラーは出ず、表示も遅くならず、軽くならないだけなので気づきにくい。画像が欠けることはなくオリジナルが配信され続けるが、この状態を検知する仕組みは弱いままになっている。
どのくらいの割合がWebPで配信されるかはサイトのアクセス傾向によって変わる。弊社のベンチマーク環境で測った例では、配信した画像の88%がWebPだった。
以前に書いたことの続き
この3つの比較は、2025年にWebP変換の適切なタイミングについてという記事で一度書いている。そのときの「オンデマンド遅延変換」が、この記事の半同期変換と同じものを指している。
変換した画像の画質については(5) WebP化によるデータ削減で見た目は劣化するかで書いている。PNGとJPEGでは事情が違い、実際に問題となりやすいのはスマホで撮った写真の向きだった。