Chrome 155でJPEG XLを表示する。picture要素のフォールバックとJPEGからの可逆変換を確かめた

Chrome 155でJPEG XLを表示する。picture要素のフォールバックとJPEGからの可逆変換を確かめた

Chrome 155でJPEG XL(.jxl)のデコードに対応しました。Chrome 155での表示、非対応版でのpicture要素のフォールバック、Acceptヘッダーのimage/jxl、既存JPEGからの可逆変換を実際に確認します。
2026.10.16

どうも!オペ部の西村祐二です!

Chrome 155で、画像形式JPEG XL(.jxl)のデコードに対応しました。フラグを有効にしなくても、<img>で.jxlを指定すれば表示されます。

ただ、すべての閲覧者が新しいChromeを使っているわけではありません。そこで、次の3点を実際に確かめました。

  • Chrome 155で.jxlがそのまま表示されるか
  • 非対応のブラウザーで<picture>要素がJPEGへフォールバックするか
  • 手元の既存JPEGを、画質を変えずにJPEG XLへ変換するとどのくらい小さくなるか

Chrome 155で変わったこと

Chrome for DevelopersのブログとChrome Platform Statusに書かれている要点は次のとおりです。

  • Chrome 155からimage/jxlをデコードできるようになりました。Chrome Platform Statusでは、デスクトップ・Android・WebView・iOSのいずれも155から対応と記載されています
  • デコーダーには、Rustで書かれたjxl-rsが使われています。画像デコーダーは攻撃を受けやすい部分のため、Chromeチームはメモリ安全な実装を選んだと説明しています
  • JPEG XLの利点として、JPEGより30〜50%高い圧縮効率、可逆圧縮、HDR対応、JPEGからの可逆トランスコードが挙げられています
  • 公式が挙げる向いている用途は、高画質な画像や可逆圧縮、特に写真や細かいプログレッシブデコードを使いたい場面です

今回の対応は、ブラウザーで表示するデコード側の対応です。JPEG XLファイルを作るには、別途エンコーダーが必要です。

picture要素で並べておけば非対応版でも壊れない

試した範囲では、次の書き方でChrome 155以降は.jxl、非対応のブラウザーは.jpgを表示しました。

index.html
<picture>
  <source type="image/jxl" srcset="photo.jxl">
  <img src="photo.jpg" alt="写真" width="768" height="512">
</picture>

また、Chrome 155以降は画像リクエストのAcceptヘッダーにimage/jxlが入りました。サーバーやCDNでこのヘッダーを見れば、同じURLで配信する画像を出し分ける判断材料に使えます。出し分けの設定そのものは、今回は試していません。

試した環境とサンプル画像

  • Google Chrome 155.0.8059.79(macOS、headlessモードで使い捨てのプロファイルを使用)
  • Chromium 156.0.8078.4(Playwright 1.64.0同梱、Linuxコンテナ)
  • 比較用の非対応版: Chromium 153.0.8010.12(Playwright 1.63.0同梱、Linuxコンテナ)
  • エンコーダー: libjxl v0.12.0のcjxl / djxl
  • 元画像: Wikimedia Commonsの写真「Loquat fruit tree.jpg」(撮影: Sabalo22、CC0 1.0)を768×512に縮小したPNG。libjpeg-turboのcjpeg -quality 85でJPEGにしたものを「既存のJPEG」として扱いました

確認用のページには、JPEG、JPEG XL、<picture>要素の3つを並べました。各画像についてimg.decode()の成否、naturalWidthとnaturalHeight、実際に読み込まれたファイル(currentSrc)を表示しています。

Chrome 155ではjxlがそのまま表示された

Chrome 155で確認用ページを開いた結果です。

Chrome 155でJPEG、JPEG XL、picture要素の3つがすべて表示され、decode()がOKになっている

<img src="photo-from-jpeg.jxl">はdecode()が成功し、768×512で表示されました。<picture>要素も.jxl側が選ばれています。headlessモードのため、画面上のUA表記はHeadlessChrome/155.0.0.0と短縮されていますが、実行したバージョンは155.0.8059.79です。

コンテナのChromium 156でも、同じページで同じ結果になりました。

非対応のChromium 153ではpicture要素がJPEGに切り替わった

同じページを、JPEG XLに対応する前のChromium 153で開きました。

Chromium 153ではJPEG XLを直接指定した画像が表示されず、picture要素はphoto.jpgを表示している

.jxlを<img>で直接指定した中央の画像は表示されず、decode()は失敗し、サイズは0×0でした。一方、右側の<picture>要素はcurrentSrcがphoto.jpgになり、JPEGが表示されています。

非対応のブラウザーからの閲覧が残るうちは、.jxlを<img>へ直接書くより、<picture>要素で従来形式と並べるほうが安全そうです。

Acceptヘッダーにimage/jxlが追加された

確認用ページを配信したローカルサーバーで、画像リクエストのAcceptヘッダーを記録しました。

# Chrome 155 / Chromium 156
image/jxl,image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8

# Chromium 153
image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8

Chrome 155とChromium 156では先頭にimage/jxlが入り、Chromium 153には含まれていませんでした。

既存のJPEGを画質を変えずにJPEG XLへ変換する

JPEG XLの特徴の1つが、既存のJPEGを画素を変えずに変換できる可逆トランスコードです。cjxlにJPEGを渡すと、この変換が既定で行われました。

cjxl photo.jpg demo.jxl
djxl demo.jxl back.jpg && cmp photo.jpg back.jpg && echo identical

cjxlでJPEGを変換し、djxlで戻したファイルが元のJPEGと一致し、サイズが96118バイトから74816バイトになった

cjxlはImplicit-default for JPEG is lossless-transcodingと表示し、JPEGを可逆トランスコードしました。djxlで戻したJPEGは元のファイルとバイト単位で一致し、SHA-256も同じでした。

ファイルサイズは次のとおりです。

ファイル サイズ
元のJPEG(quality 85) 96,118 bytes
JPEGから可逆変換したJPEG XL 74,816 bytes(約22%減)

画像の見た目を変えずに、約22%小さくなりました。必要になれば元のJPEGへ完全に戻せるので、既存の画像資産を置き換えるときも元ファイルを失いません。

公式の「30〜50%高い圧縮効率」とは条件が違う点に注意が必要です。今回の約22%は、すでにJPEGで圧縮された画像を、画素を変えずに詰め直した結果です。画質を指定して新たにエンコードした場合の数値ではありません。結果は元のJPEGの品質や画像の内容によっても変わります。

参考として、可逆圧縮でも比べました。元のPNG(806,139 bytes)をcjxl -d 0で可逆のJPEG XLにすると302,875 bytesになり、約62%小さくなりました。背景のぼけが大きく、なだらかな領域が多い写真なので、可逆圧縮で縮みやすい条件だったと考えられます。

試し始めるならJPEGの可逆変換から

新しく使い始めるなら、既存JPEGの可逆変換から試すのが手軽だと感じました。画質を決め直す必要がなく、元のJPEGにも戻せるためです。

今回確認していないこと

次の点は確認していません。

  • Android・WebView・iOS版Chrome、WindowsとLinuxのデスクトップ版Chromeでの表示
  • アニメーション、HDR・広色域の表示、プログレッシブデコードの見え方
  • CSSのbackground-imageやimage-set()でのJPEG XL指定
  • FirefoxとSafariでの表示
  • CDNでのAcceptヘッダーによる出し分け
  • AVIFなど他形式との、画質をそろえた容量比較

まとめ

Chrome 155では、.jxlを<img>や<picture>要素でそのまま表示できました。非対応のChromium 153では.jxlを直接指定した画像は表示されませんでしたが、<picture>要素はJPEGへフォールバックしました。Chrome 155以降はAcceptヘッダーにimage/jxlが入るため、サーバー側での出し分けにも使えます。

既存のJPEGはcjxlで可逆変換でき、今回の写真では元に戻せる状態のまま約22%小さくなりました。導入するなら、既存JPEGを可逆変換し、<picture>要素で元のJPEGと並べて配信する形から試すのが良さそうです。

誰かの参考になれば幸いです。

参考リンク

この記事をシェアする

関連記事