Firs Meaningful Paintの高速化
Webアプリケーションの初期描画をを早くしたいです。 今風に言うとFirst Meaningful Paintの高速化です。
大量のデータを読み込んだ際にすべての情報をレンダリングすると時間がかかります。 最初は、HTMLページの上の表の表示領域内のdivを描画し、下の方、表示領域外にあるdivの描画をスキップしたいです。 スキップした要素はスクロールして表示領域に入った時に描画します。
divを表示する位置を計算するロジックがすでにあります。 計算した表示位置が表示領域内にあるかどうかを判定したいです。
あるdiv要素か表示領域内にあるかどうか判定
ロジックの確認のために、あるdiv要素か表示領域内にあるかどうか判定するCodepenを作りました。
結果は開発コンソールに出力しています。
ブラウザの開発ツールを起動してもらうか、Codepenで開いてConsole
を開いてもらうと、出力が確認できます。
See the Pen 表示されている要素を検出する by shigeru.nakajima (@ledsun) on CodePen.
判定条件
結論は次の判定になりました。 横スクロールは想定していません。
const { top, bottom } = div.getBoundingClientRect(); if (0 <= bottom && top <= clientHeight) { ret.push(div.id); }
clientHeightはdocument.documentElement.clientHeight
です。
clientHeightはブラウザの表示している領域です。
非常に似たようなプロパティにwindow.innerHeight
があります。
これはスクロールバーが表示されているときにスクロールバーを含んだ高さを返します。
今回は人間の目に見える領域が取得したかったので、スクロールバーを含まないclientHeightを選択しました。*1
またwindow.visualViewport.height
というプロパティもあります。
これはタブレットまたはスマートフォンで、ピンチアウト、ピンチインして拡大縮小したときに見えている領域が取れるようです。
今回はタブレット、スマートフォンは考慮しませんでした。
div側は、getBoundingClientRectを使うと表示領域内でのtop, bottomが取れます。 これとclientHeightを比較すると簡単に判定できます。 div全体でなく、一部が表示領域に入った場合にtrueと判定しています。
参考
- javascript - How to get the browser viewport dimensions? - Stack Overflow
- VisualViewport - Web APIs | MDN
- ウェブページがピンチアウト・ズームされているかどうか検出する方法 - Qiita
*1: window.innerHeight を使っても、誤差の範囲で、ユーザーに見える情報にも性能にも影響は無いと思います。