水たまりは希望を写している

picture 要素もちゃんと Preload Scanner が動くのでどんどん使っていこう

先日、このツイートを見た。

画像のサイズを変えてもパフォーマンスは改善されない、というのは同意できるが、2番目の「picture タグによる画像出し分けは、Preload Scanner が効かない~」について疑問が残る。果たして本当に picture 要素は Preload Scanner が効かないのだろうか。

Preload Scanner とは

Preload Scanner (プリロード スキャナ) は、ブラウザが HTML を DOM としてパースする前に、簡易的なパーサーを使用してウェブページに必要なリソースを事前にダウンロードする (プリロードする) 仕組みのことだ。これは HTML の仕様ではなく、あくまでもブラウザが独自実装しているものであるが、大抵のブラウザにこの機能が備わっている。

script 要素や img 要素などによるリソースの読み込みがプリロードの対象なのだが、例えば document.createElementimg 要素をつくって DOM に挿入するといった JavaScript コードによるリソースの読み込みは、Preload Scanner が検知することができない (JavaScript を実行するまでリソースを読むべきか分からないから)。

Preload Scanner を無効化する

Chrome 125 からは、Chrome の起動する際に渡すパラメーターに --enable-features=SkipPreloadScanning を追加すると、Preload Scanner を無効化することが可能である。今回はこれを検証に使う。

本当に picture 要素は Preload Scanner が効かないのか

https://labs.aioilight.space/responsive-image/picture-tag.html

このページを用意した。

<picture>
  <source srcset="sp.webp" media="(max-width: 480px)">
  <img src="pc.webp" alt="野良猫の写真。">
</picture>

このような picture 要素が挿入されている。

Preload Scanner を無効化した Chrome でパフォーマンスを見てみる。HTML が返却された後、HTML のパースが始まり、DOMContentLoaded の直前で pc.webp へのリクエスト送信が始まる。このことから、DOM の構築中に picture 要素を解析し、ダウンロードすべきリソースを決定してダウンロードしようとしていることが分かる。

次に、Preload Scanner が有効なふつうの Chrome でパフォーマンスを見てみる。HTML が返却された後、HTML のパースが始まる前に pc.webp へのリクエスト送信が始まる。このことから Preload Scanner によって picture 要素の画像がプリロードされていることが分かる。

追加情報

whatwg の Preload Scanner 標準化についての issue で、Chrome の Preload Scanner の挙動についてのコメントがある。

PreloadScanner logic got more and more complicated over time. For example, it simulates the media query match so that it won’t request images of the wrong resolution.

Preload Scanner は高速なパーサーであるものの、間違った解像度の画像をリクエストしないよう「メディアクエリのシミュレート」をするなど、複雑化している、と書かれている。

この記述は、間違いなく pictureimg 要素の srcset 属性の話だろう。

まとめ

picture 要素も Preload Scanner が動くので、どんどん picture 要素を使っていこう。

ちなみに、単にメディアクエリで切り替えるだけでなく、

https://labs.aioilight.space/responsive-image/picture-tag2.html

このページのように、画面解像度に応じた画像ファイルの選択といった、少し複雑な記述でもちゃんと効いている。

この記事を書いた人

AioiLight

Web とか Android とかをやってる人。アニメ・ゲームが好きなはずなのに消費しきれない毎日。

Twitter (@aioilight)