レイジーロードがブラウザネイティブでサポートされそう

画像が100個並んだページがあるとしましょう。
普通にimgタグを使っていると、全ての画像が読み込まれるまで画面がまともに描画されず、とても重いページになります。
そこで初期表示を軽くするためにLazy Loadという技術が生まれました。
まずは画面に表示される部分の画像だけを先に読んで画面を表示して、残った部分は後からゆっくりロードしようというものです。

一番手っ取り早いやりかたとしては、HTMLにダミーのタグだけ用意しておいて、onloadあたりで要素を追加するかんじでしょうか。

```js
<div id="dummy_image" />

$.on('load',function(){
    $('#dummy_image').append('<img src="hoge.png">');
});
```

もちろんこんな適当な書き方はアレなので、きちんと書けるようにした[ライブラリ](https://qiita.com/tkhr/items/4b5e7f2a384dc4fccb20)も多く存在します。

そして先日、わざわざJavaScriptやライブラリを使わなくてもいいように、ブラウザ自身とHTMLで対応しようぜという[Proposal](https://docs.google.com/document/d/1e8ZbVyUwgIkQMvJma3kKUDg8UUkLRRdANStqKuOIvHg/edit)が提出されました。

以下はProposalを紹介している[A Native Lazy Load for the Web](https://css-tricks.com/a-native-lazy-load-for-the-web-platform/)の日本語訳です。

# A Native Lazy Load for the Web

著：[BEN SCHWARZ](https://css-tricks.com/author/ben-schwarzgmail-com/)

"Blink LazyLoad"と呼ばれるChromeの新たな機能は、ページをロードしたときに最初に表示されない画像(Below the foldと呼ばれる)や、サードパーティ製iframeの読み込みを後回しにすることによって、パフォーマンスを劇的に向上させるように設計されています。

この大胆な提案の目的は、最初に表示されるコンテンツ(Above the foldと呼ばれる)のレンダリング速度を表示させること、そしてネットワーク転送量やメモリ使用量を削減することです。

## How will it work?

一般的に、重要度の低いコンテンツは表示を後回しにすることで、体感的なローディング速度を上昇させることができます。
このプロポーザルが通過したら、ページのロード中、自動的に最適化が行われるようになります。

・画像とiframeは、その重要度を判定される。
・重要でないと判断されると、後回しになるか全く読み込まれなくなる。
・ユーザが対象の近くまで画面をスクロールすると読み込みが始まる。
・画像が取得されるまでは空のプレースホルダになっている。

[Proposal](https://docs.google.com/document/d/1e8ZbVyUwgIkQMvJma3kKUDg8UUkLRRdANStqKuOIvHg/edit)では、いくつかの興味深い提案がなされています。

・LazyLoadはLazyImagesとLazyFramesという2種の異なるメカニズムで構成されている。
・ユーザが画面をスクロールして、画面が決められたピクセル数まで近付くと、画像とiframeのロードが行われる。ピクセル数は以下の3要因によって決定される。
　・画像であるかiframeであるか
　・Data Saverが有効か無効か
　・[接続種別](https://googlechrome.github.io/samples/network-information/)
・描画範囲外である画像は、まず[最初の数バイトだけを取得](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests)して画像サイズを決定し、該当サイズのプレースホルダを作成する。

開発者は、特定要素を遅延ロードさせたい/させたくない場合に[lazyload属性](https://whatpr.org/html/3752/urls-and-fetching.html#lazy-loading-attributes)で任意に指定できます。
以下は遅延ロードを指定する例です。

```html
	<iframe src="ads.html" lazyload="on"></iframe>
```

属性値は以下の3種類です。

・"on" - 遅延ロードを推奨する。
・"off" - 描画範囲にかかわらず、すぐに読み込みを行う。
・"auto" - ブラウザに決定させる。未指定と同じ。

## Implementing a secure LazyLoad policy

LazyLoadの[ポリシー](https://www.chromestatus.com/feature/5641405942726656)は、[コンテンツセキュリティポリシー](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)と同じように、ドメイン単位で遅延ロードをオプトインもしくはオプトアウトできるようにする機能を提供します。

セキュリティポリシーのドキュメントについては[Pull Request](https://github.com/WICG/feature-policy/pull/196)が存在しますが、まだマージされていません。

## What about backwards compatibility?

現時点では、これらのページ最適化が既存サイトとの互換性の問題を引き起こすかどうかを判断することは困難です。

サードパーティのiframeは広告・分析・認証などの目的で大量に使用されています。
ユーザが全くスクロールしなかったなどの理由で重要なiframeの読み込みが遅れた、あるいは全く読み込まれなかった場合、予期できない大規模な影響が現れる可能性があります。
画像やiframeの中身が存在していることが前提であるイベントをonloadで動かしているような場合にも重大な問題に直面するかもしれません。

Chromeの自動最適化機能は、そのような大きな問題を起こさないようにレンダリング速度を上げようとしています。
Googleの開発チームは、LazyLoadが及ぼすパフォーマンス特性を慎重に計測しています。

## Enabling LazyLoad

執筆時点ではLazyLoadは[Chrome Canary](https://www.google.com/chrome/canary/)でのみ使用することができ、以下の2つの設定を有効化する必要があります。

```text
chrome://flags/#enable-lazy-image-loading
chrome://flags/#enable-lazy-frame-loading
```

アドレスバーに`chrome://flags`と入力することで設定画面に移動できます。

## References and materials

・[LazyLoad public proposal](https://docs.google.com/document/d/1e8ZbVyUwgIkQMvJma3kKUDg8UUkLRRdANStqKuOIvHg/edit)
・[HTML Living Standard Pull Request - lazyload attribute](https://whatpr.org/html/3752/urls-and-fetching.html#lazy-loading-attributes)
・[HTTP Range Requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests)
・[Chrome Platform Status - Feature policy: lazyload](https://www.chromestatus.com/feature/5641405942726656)
・[LazyLoad Frames was merged into Chromium](https://bugs.chromium.org/p/chromium/issues/detail?id=873358)
・[Calibre performance monitoring](https://calibreapp.com/)

## In closing

次の10億人をWebの世界に歓迎するための、ブラウザ、コネクション、ユーザエクスペリエンスの複雑さを理解するための試みは始まったばかりであることを認めよう。


# コメント欄

「デフォルトをoffではなくautoにするのは賢明ではなさそう。言及されている以外にも問題を引き起こす状況が幾つも考えられる。オプトインにするべき。」
「全く同意、デフォルトはオフにして、開発者が任意で有効にしたほうがいい。でも導入自体は歓迎。」
「最初に思い浮かべたのは広告。LazyLoadがデフォルトになると広告収入が激減しそう。」
「描画範囲外にある画像のサイズを調べるリクエストは必ず発行されるん？たいていはwidth/heightが書かれてると思うんだけど。」


# 感想

サードパーティ実装であるような"最初は軽い画像を出しておいて読み込みが終わったら入れ替える"みたいな機能はありません。
しかし、imgタグに`lazyload="on"`って入れるだけでいいので、実装は非常に容易になります。
iframeにも対応しているので、遅いと文句を言われがちなソーシャルタグもLazyLoadにすることでストレスは緩和されるでしょう。

デフォルトがautoですと間違いなく広汎なサイトに悪影響が出ますから、当面はデフォルトoffにしたほうがいいでしょうね。
あとはmetaタグあたりで`<meta name="lazyload" content="default:on;pixel:10;">`みたいに (文法は適当) 設定できればより便利かもしれません。

そういえばLazyLoadは[SEOに弱い](https://qiita.com/ryo_hisano/items/e8554777793551c105bd)という話をよく聞きますが、このProposalはGoogleの発案ですから、そこらへんの対策はばっちりしてあるに違いありません。
たぶん。