2021年に最も最適化されたWeb画像の読み込み



この記事では、画面に表示されたときに必要なネットワーク帯域幅とプロセッサの負荷を減らす、画像の読み込みを最適化するための8つの手法を共有します。再現しやすくするための注釈付きHTMLの例を次に示します。いくつかの技術は長い間知られており、いくつかは比較的最近登場しました。理想的には、お気に入りのWebドキュメント公開メカニズム(CMS、静的サイトジェネレーター、Webアプリケーションフレームワークなど)は、これらすべてをすぐに実行できるはずです。



まとめると、この手法は次の方法でGoogle Core WebVitalsのすべての要素を最適化します





実際のすべてのテクニックを確認するには、このイメージをロードするためのソースコードを確認してください。



https://www.industrialempathy.com/img/remote/ZiClJf.jpg
<img loading="lazy" decoding="async" style="background-size: cover; background-image: none;" src="/img/remote/ZiClJf.avif" alt="Sample image illustrating the techniques outlined in this post." width="4032" height="2268">

      
      







最適化手法



レスポンシブレイアウト



この簡単な手法により、アスペクト比を維持しながら、画像が利用可能な水平方向のスペースを占めることができます。2020年に、ブラウザは、要素img



に属性width



が含まれている 場合、画像が読み込まれる前に、画像に適切な量の垂直方向のスペースを予約することを学習しました height



これにより、レイアウトの累積的なシフトが回避されます。



<style>
 img {
   max-width: 100%;
   height: auto;
 }
</style>
<!-- Providing width and height is more important than ever. -->
<img height="853" width="1280" … />

      
      





レイジーレンダリング



2番目の手法はより複雑です。新しいCSS属性 content-visibility: auto



は、準備ができるまで画像を配置することを考えないようにブラウザに指示します。このアプローチにはいくつかの利点がありますが、その主な利点は、ブラウザがぼやけたプレースホルダー画像または画像自体を受信するまで、それをデコードせず、プロセッサリソースを節約することです。



contains-intrinsic-sizeは不要になりました



記事の以前のバージョンではcontain-intrinsic-size



、を使用するときにCLS効果回避する方法について説明 しました content-visibility: auto



しかし、クロム88で、これはのための画像の場合には、もはや必要ではない width



height



2021年1月27日の時点では content-visibility: auto



、他のブラウザエンジン
はまだ実装されていないため、 Chromiumの主導に従う可能性があります。そうそう、今はずっと簡単です!



<style>
 /* This probably only makes sense for images within the main scrollable area of your page. */
 main img {
   /* Only render when in viewport */
   content-visibility: auto;
 }
</style>

      
      





AVIF



AVIFは、ブラウザでサポートされている最新のグラフィック形式です。 ChromiumとFirefoxのフラグでサポートされるようになりました。 Safariはまだ動作しませんが、Appleはフォーマットを開発したグループの一部であるため 、このブラウザは将来的にAVIFもサポートする予定です。



この形式は、JPEGよりもはるかに優れているという点で注目に値します。また、これはWebP形式と比べて遜色ありません。この形式では、画像が常にJPEGよりも小さいとは限らず、プログレッシブ読み込みがサポートされていないためにリソース消費量が増える可能性があります。



AVIFのプログレッシブ拡張を実装するには、を使用できます picture







要素は実際には img



ネストされています picture



..。これは、をimg



サポートしていないブラウザのフォールバックソリューションと呼ばれることもある ため、混乱する可能性があります picture



が、実際には、この要素は選択src



役立つだけで あり、独自のレイアウトはありません。要素img



描画され 、それにスタイルを適用します。



最近まで、サーバー側でAVIFイメージを実装することは非常に困難でしたが、sharpなどの最近のバージョンのライブラリで はこのタスクがはるかに簡単になりました。



<picture>
 <source
   sizes="(max-width: 608px) 100vw, 608px"
   srcset="
     /img/Z1s3TKV-1920w.avif 1920w,
     /img/Z1s3TKV-1280w.avif 1280w,
     /img/Z1s3TKV-640w.avif   640w,
     /img/Z1s3TKV-320w.avif   320w
   "
   type="image/avif"
 />
 <!-- snip lots of other stuff -->
 <img />
</picture>

      
      





正しいピクセル数を読み込んでいます



上記のコードには属性 srcset



とがあり sizes



ます。セレクターw



使用 して、特定のデバイスで画像をレンダリングするために必要な物理的なピクセル数に基づいて、使用するURLをブラウザーに指示します。この量は、属性sizes



(メディアクエリからの式)に基づいて計算される画像の幅によって異なり ます。



これにより、ブラウザは常に可能な限り最小の画像をロードし、特定のデバイスで最高の品質を提供します。または、ユーザーがデータ保存モードを有効にしている場合は、最小の画像を選択できます。



フォールバックソリューション



古い画像形式のみをサポートするブラウザの場合、次の方法でsrcset



より多くのraw要素提供でき ます。



<source
 sizes="(max-width: 608px) 100vw, 608px"
 srcset="
   /img/Z1s3TKV-1920w.webp 1920w,
   /img/Z1s3TKV-1280w.webp 1280w,
   /img/Z1s3TKV-640w.webp   640w,
   /img/Z1s3TKV-320w.webp   320w
 "
 type="image/webp"
/>
<source
 sizes="(max-width: 608px) 100vw, 608px"
 srcset="
   /img/Z1s3TKV-1920w.jpg 1920w,
   /img/Z1s3TKV-1280w.jpg 1280w,
   /img/Z1s3TKV-640w.jpg   640w,
   /img/Z1s3TKV-320w.jpg   320w
 "
 type="image/jpeg"
/>

      
      





キャッシュと不変のURL



画像のURLに、画像が占めるバイト数のハッシュを埋め込みます。上記の例では、を使用して実行しました Z1s3TKV



画像を変更すると、URLも変更されます。つまり、画像の無限キャッシュを適用できます。キャッシングヘッダーはのようになり cache-control: public,max-age=31536000,immutable



ます。



immutable



意味的に正しい意味ですが cache-control



、今日はブラウザのサポートがほとんどありません(Chrome、あなたを見ています)。 max-age=31536000



-年間を通じてフォールバックキャッシュ方式。 public



CDNが画像をキャッシュし、ネットワークエッジから配信するために必要です。ただし、このアプローチは、プライバシーポリシーに違反していない場合にのみ使用できます。



遅延読み込み



loading=«lazy»



要素に追加する ことで、 img



レンダリングの準備ができたときにのみ画像のフェッチを開始するようにブラウザに指示します。



<img loading="lazy" … />

      
      





非同期復号化



decoding=«async»



要素に追加 する img



ことで、この手順がユーザーの邪魔にならないように、ブラウザがメインストリームの外部で画像を復号化できるようにします。古いブラウザではデフォルトで常に適用できるとは限らないことを除いて、このソリューションに目立った欠陥はないはずです。



<img decoding="async" … />

      
      





ぼやけたスタブ



ファジースタブは、ネットワークを介してデータを転送せずに、後で読み込まれる本格的な画像のアイデアをユーザーに提供するインライン画像です。



https://www.industrialempathy.com/img/blurry.svg





いくつかの実装上の注意:



  • スタブはbackground-image



    画像のようにインライン化されます。この手法では、メイン画像が読み込まれるときに文字通りスタブを非表示にすることで2番目のHTML要素を削除できます。JavaScriptは必要ありません。
  • メインの画像データURIは、SVG画像データURIにラップされています。これは、CSSフィルターを使用せずにSVGレベルでぼかしが行われるために行われます。つまり、ぼかしは、レイアウトごとではなく、SVGによってラスタライズされたときに画像ごとに1回行われます。これにより、プロセッサリソースが節約されます。


<img
 style="
     …
     background-size: cover;
     background-image:
       url('data:image/svg+xml;charset=utf-8,%3Csvg xmlns=\'http%3A//www.w3.org/2000/svg\'

xmlns%3Axlink=\'http%3A//www.w3.org/1999/xlink\' viewBox=\'0 0 1280 853\'%3E%3Cfilter id=\'b\' color-interpolation-filters=\'sRGB\'%3E%3CfeGaussianBlur stdDeviation=\'.5\'%3E%3C/feGaussianBlur%3E%3CfeComponentTransfer%3E%3CfeFuncA type=\'discrete\' tableValues=\'1 1\'%3E%3C/feFuncA%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter=\'url(%23b)\' x=\'0\' y=\'0\' height=\'100%25\' width=\'100%25\'
       xlink%3Ahref=\'data%3Aimage/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAGCAIAAACepSOSAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAs0lEQVQI1wGoAFf/AImSoJSer5yjs52ktp2luJuluKOpuJefsoCNowB+kKaOm66grL+krsCnsMGrt8m1u8mzt8OVoLIAhJqzjZ2tnLLLnLHJp7fNmpyjqbPCqLrRjqO7AIeUn5ultaWtt56msaSnroZyY4mBgLq7wY6TmwCRfk2Pf1uzm2WulV+xmV6rmGyQfFm3nWSBcEIAfm46jX1FkH5Djn5AmodGo49MopBLlIRBfG8yj/dfjF5frTUAAAAASUVORK5CYII=\'%3E%3C/image%3E%3C/svg%3E');
   "
 …
/>

      
      





(オプション)JavaScriptの最適化



画像がすでに読み込まれている場合でも、ブラウザはぼやけたスタブをラスタライズするように強制される場合があります。この問題は、起動時にラスタライズを削除することで解決できます。さらに、画像に透明な領域がある場合、この最適化は必須になります。そうでない場合、スタブが画像を通して表示されます。



<sript>
 document.body.addEventListener(
   "load",
   (e) => {
     if (e.target.tagName != "IMG") {
       return;
     }
     // Remove the blurry placeholder.
     e.target.style.backgroundImage = "none";
   },
   /* capture */ true
 );
</sript>

      
      





さらに



説明されているすべての最適化を実装する便利なツール: 11-high-performance-blog



All Articles