この記事では、画面に表示されたときに必要なネットワーク帯域幅とプロセッサの負荷を減らす、画像の読み込みを最適化するための8つの手法を共有します。再現しやすくするための注釈付きHTMLの例を次に示します。いくつかの技術は長い間知られており、いくつかは比較的最近登場しました。理想的には、お気に入りのWebドキュメント公開メカニズム(CMS、静的サイトジェネレーター、Webアプリケーションフレームワークなど)は、これらすべてをすぐに実行できるはずです。
まとめると、この手法は次の方法でGoogle Core WebVitalsのすべての要素を最適化します 。
- サイズの縮小、キャッシュ、遅延読み込みを通じて、主要なコンテンツの問題(最大コンテンツフルペイント(LCP))を最小限に抑えます。
- ゼロ累積レイアウトシフトの保持(累積レイアウトシフト(CLS));
- (実行のメインスレッドの)プロセッサ消費を減らすことにより、最初の入力の遅延(最初の入力遅延(FID))を減らします。
実際のすべてのテクニックを確認するには、このイメージをロードするためのソースコードを確認してください。
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