Chromeに実装される新機能『loading属性』について解説、ついにブラウザがネイティブで遅延ロードをサポート
Post on:2019年4月24日
Google ChromeのEngineering ManagerであるAddy Osmani氏による、Chrome 75でリリース予定のloading属性についての解説を紹介します。
loading属性とはブラウザがネイティブで遅延ロードをサポートするもので、img要素やiframe要素を簡単に遅延ロードさせることができます。以前は、lazyload属性として開発されていましたが、loading属性という名前に変わる、とのことです。
Native image lazy-loading for the web!
by Addy Osmani
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- Chrome 75でリリース予定のloading属性
- ブラウザがネイティブで遅延ロードをサポート
- loading属性とは
- loading属性の機能
- loading属性を使用したデモ
- Chrome実装の詳細
- サーバーでのローディングサポート
- まとめ
- リファレンス
Chrome 75でリリース予定のloading属性
この記事ではimg要素とiframe要素にネイティブの遅延ロードをもたらす新しいloading属性について解説します。まずは、実際に動作するコードをお見せします。
1 2 |
<img src="celebration.jpg" loading="lazy" alt="..." /> <iframe src="video-player.html" loading="lazy"></iframe> |
わたし達はChrome 75でサポートすることを望んでおり、まもなくリリースする機能の徹底的な検証に取り組んでいます。このloading属性の仕組みを紹介しましょう。
ブラウザがネイティブで遅延ロードをサポート
Webページには多くの場合、大量の画像が含まれています。これはデータの使用量、ページの肥大化、ページの読み込み速度に影響します。そして、これらの画像の多くはスクリーン外にあるため、表示するにはユーザーがスクロールする必要があります。
今までは、スクリーン外の画像がページの読み込み時間に与える影響を少なくする目的で、ユーザがスクロールするまでこれらの画像の取得を遅延するためにデベロッパーはJavaScriptライブラリ(LazySizesのような)を使う必要がありました。
WebPageTest(211枚の画像を使用した遅延ロードのデモページ)
ブラウザがネイティブで、スクリーン外の画像は自動的に読み込まないようになるとしたらどうでしょう? ビューポートのコンテンツの読み込みは速くなり、ネットワークデータ全体の使用量が減り、ローエンドのデバイスではメモリ使用量が減ります。
私は、img要素とiframe要素のための新しいloading属性が間もなく可能になることを共有できてうれしく思います。
loading属性とは
loading属性を使用すると、ブラウザはスクリーン外の画像やiframeをユーザーがスクロールするまで読み込みを遅らせることができます。
loading属性は3つの値をサポートします。
-
- lazy
- 遅延ロードに適した値です。
-
- eager
- 遅延ロードには適してません、すぐにロードする値です。
-
- auto
- 遅延ロードするかどうかをブラウザに委ねます。
loading属性を定義しない場合は、loading=autoを定義した場合と同じになります。
遅延ロードさせるには、loading=lazyを定義
<img>と<iframe>のloading属性は、HTML標準の一部として取り組まれています。
loading属性の実装例
loading属性は<iframe>と<img>(srcsetおよび<picture>内も含む)で機能します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!-- ユーザーが近くにスクロールしたときにスクリーン外の画像を遅延ロードする --> <img src="unicorn.jpg" loading="lazy" alt=".."/> <!-- 遅延ロードはせずに、画像をすぐにロードする --> <img src="unicorn.jpg" loading="eager" alt=".."/> <!-- 画像を遅延ロードするかどうかはブラウザが決定する --> <img src="unicorn.jpg" loading="auto" alt=".."/> <!-- picture要素における定義方法、<img>にloading属性を記述する --> <picture> <source media="(min-width: 40em)" srcset="big.jpg 1x, big-hd.jpg 2x"> <source srcset="small.jpg 1x, small-hd.jpg 2x"> <img src="fallback.jpg" loading="lazy"> </picture> <!-- srcsetが指定されている画像を遅延ロードする --> <img src="small.jpg" srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w" sizes="(min-width: 36em) 33.3vw, 100vw" alt="A rad wolf" loading="lazy"> <!-- ユーザーが近くにスクロールしたときにスクリーン外のiframeを遅延ロードする --> <iframe src="video-player.html" loading="lazy"></iframe> |
「ユーザーが近くにスクロールしたとき」の定義はブラウザに任されています。一般的に期待されるのは、ブラウザがビューポートに入る少し前に遅延された画像やiframeコンテンツを取得し始めることです。こうすることで、ユーザーがスクロールした時までに、画像やiframeコンテンツの読み込みが完了します。
メモ: loading属性という名前は、decoding属性とより密接な関係があるため提案しました。lazyload属性などの以前の提案は、複数の値(lazy、eager、auto)をサポートする必要があるため、却下されました。
loading属性の機能
遅延ロードのためにJavaScriptライブラリで適用できることの重要性を念頭に置いています(クロスブラウザをサポートするため)。loadingは、下記のように検出できます。
1 2 3 4 5 6 7 8 |
<script> if ('loading' in HTMLImageElement.prototype) { // ブラウザがloadingをサポートしている場合 } else { // ポリフィル / JavaScriptライブラリで適用する // 代わりに遅延ロードを実行 } </script> |
メモ: プログレッシブエンハンスメントとしてloadingを使用することもできます。この属性をサポートするブラウザは、loading=lazyを指定した新しい遅延ロード動作と、まだ画像を読み込まないブラウザを取得できます。
クロスブラウザ対応、画像の遅延ロード
クロスブラウザに対応したサポートが重要な際に、マークアップで<img src = unicorn.jpg loading = lazy />を使用している場合は、ライブラリを検出して遅延ロードするだけでは不十分です。
新しい属性をサポートしていないブラウザで読み込みが行われないようにするには、マークアップで<img data-src=unicorn.jpg />のように(src、srcset、または<source>ではなく)する必要があります。loadingがサポートされている場合はJavaScriptを使用して適切な属性に変更し、サポートされていない場合はライブラリを読み込むことができます。
下記はどのように見えるかの例です。
- ビューポート内・折り目上の画像は、通常の<img>タグです。data-srcはプリロードスキャナを無効にするので、ビューポートにある可能性があるすべてのものについては回避したいと思います。
- サポートされていないブラウザでの負荷を避けるために、画像にdata-srcを使用します。loadingがサポートされている場合は、data-srcをsrcに交換します。
- loadingがサポートされていない場合は、フォールバック(LazySizes)をロードして開始します。ここでは、遅延ロードしたい画像をLazySizesに任せる方法として、class=lazyloadを使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<!-- このビューポートイメージは普通にロードします --> <img src="hero.jpg" alt=".."/> <!-- 残りの画像は遅延ロードさせます --> <img data-src="unicorn.jpg" loading="lazy" alt=".." class="lazyload"/> <img data-src="cats.jpg" loading="lazy" alt=".." class="lazyload"/> <img data-src="dogs.jpg" loading="lazy" alt=".." class="lazyload"/> <script> (async () => { if ('loading' in HTMLImageElement.prototype) { const images = document.querySelectorAll("img.lazyload"); images.forEach(img => { img.src = img.dataset.src; }); } else { // Dynamically import the LazySizes library const lazySizesLib = await import('/lazysizes.min.js'); // Initiate LazySizes (reads data-src & class=lazyload) lazySizes.init(); // lazySizesはグローバルで機能します。 } })(); </script> |
loading属性を使用したデモ
100匹の子ネコ画像を使用したloading=lazyのデモを見てみてください。
あなたが検証するであろう内容を動画に記録しました。
Chrome実装の詳細
loading属性を本番環境で使用する前に、安定版がリリースされるまで待つことを強くお勧めします。テストする際には、下記の情報が役立つかもしれません。
loading属性を試す方法
Chromeで chrome://flags にアクセスし、「lazy frame loading」と「lazy image loading」の両方のフラグをオンにして、Chromeを再起動してください。
設定
Chromeの遅延ロードの実装は、現在のスクロール位置の近さだけでなく、接続速度にも基づいています。異なる接続速度に対するレイジーフレームおよび画像ロード時のビューポートからの距離のしきい値はハードコードされていますが、コマンドラインから上書きできます。以下が画像の遅延ロード設定を上書きする例です。
1 |
canary --user-data-dir="$(mktemp -d)" --enable-features=LazyImageLoading --blink-settings=lazyImageLoadingDistanceThresholdPxUnknown=5000,lazyImageLoadingDistanceThresholdPxOffline=8000,lazyImageLoadingDistanceThresholdPxSlow2G=8000,lazyImageLoadingDistanceThresholdPx2G=6000,lazyImageLoadingDistanceThresholdPx3G=4000,lazyImageLoadingDistanceThresholdPx4G=3000 'https://mathiasbynens.be/demo/img-loading-lazy' |
上記のコマンドは、(現在の)デフォルト設定に対応しています。スクロール位置が画像の400px以内の場合にのみ遅延ロードを開始するには、すべての値を400に変更してください。下記は動画に使用した1pxのバージョンです。
1 |
canary --user-data-dir="$(mktemp -d)" --enable-features=LazyImageLoading --blink-settings=lazyImageLoadingDistanceThresholdPxUnknown=1,lazyImageLoadingDistanceThresholdPxOffline=1,lazyImageLoadingDistanceThresholdPxSlow2G=1,lazyImageLoadingDistanceThresholdPx2G=1,lazyImageLoadingDistanceThresholdPx3G=1,lazyImageLoadingDistanceThresholdPx4G=1 'https://mathiasbynens.be/demo/img-loading-lazy' |
今後数週間で実装が安定するにつれて、デフォルト設定が変わる可能性が高いです。
デベロッパーツール
Chromeでのロードの仕組みは、ページを読み込む際に画像の最初の2Kbを取得することです。サーバーが範囲要求をサポートしている場合、最初の2Kbには画像サイズの情報が含まれている可能性があります。この情報により、同じサイズのプレースホルダーを生成・表示することができます。また、最初の2Kbにはアイコンなどのアセットの画像全体も含まれている可能性があります。
ユーザーがこれらを表示しようとしている時に、Chromeは画像ファイルの残りを取得します。デベロッパーツールでの注意点は、1.ネットワークパネルに2回フェッチされて表示される、2.各画像に対して2つのリクエストが必要になることです。
サーバーでのローディングサポート
フォールバックのライブラリをロードする必要があるかどうかを判断するためにクライアントサイドのJavaScript機能検出に頼る必要はありません。JavaScriptの遅延ロードのライブラリを含むHTMLを提供する前にこれを処理します。クライアントヒントはそのようなチェックを可能にするかもしれません。
ローディングのプリファレンスを伝えるためのヒントが検討されていますが、現在は初期の議論段階にあります。
参考: Provide a LazyLoad Client Hint
まとめ
<img loading>について、あなたがどう思うか教えてください。私は、人々がどのようにクロスブラウザの物語を見つけているのか、そしてわたし達が見逃している特別な問題があるのか興味があります。
リファレンス
Simon Pieters, Yoav Weiss, Mathias Bynensのフィードバックに感謝します。そして、LazyLoadの作業をしてくれたBen Greenstein, Scott Little, Raj T and Houssein Djirdehに感謝します。
sponsors