HTMLパース処理を中断して強制初回描画する

サイトの高速化について試行錯誤していたら、面白そうな現象を発見したので覚書です。

なにをするのか?

ページがヘッダー部・コンテンツ部・フッター部に分割されているものとします。この時、「ヘッダー部のみをコンテンツ部・フッター部のHTMLパース処理を待たずに表示する」です。意図せずに、このような表示になることはあります。ですが、これは意図的にこの表示を作り出します。

loading

コード

<html>
<head>...</head>
<body>
  <header id="site-header">...<header>
  <script>document.body.clientHeight;</script>

  <div id="site-content">...</div>

  <footer id="site-footer">...</footer>
</body>
</html>

詳細な動作原理は不明です。ですが、想像するに高さ計算によってヘッダー部のレイアウト(リフロー)を強制的に実施できるのではないかと考えます。そして、通常HTMLパースが終わるまで発生しないレイアウトを強制的に実施することでヘッダー部のみレイアウトが完了し、ヘッダーのみの初回表示が実現できるものと考えます。

※十分に遅いページでないと、再現を目視できません。
※強制的にペイントを発生させているわけではなく、レイアウトを発生させています。そのため、確実に描画するとは限りません。

備考

この方法でFP(First Paint)・FCP(First Contentful Paint)を高速化できるものと考えます。ただし、ページ全体の描画は遅くなる可能性があります。

※外部スタイルのスクリプトブロックに注意して下さい。


次のブログ記事に本件の該当箇所がありました。ブラウザは、スクリプトが次の要求をした場合、リフローのキューをフラッシュしこれまでのすべてをバッチ処理で実行するようです。そして、一度レンダリングツリーが構築されると、ブラウザはレンダリングツリーノードをスクリーン上にペイント(描画)することができるようになるようです。

offsetTop, offsetLeft, offsetWidth, offsetHeight
scrollTop/Left/Width/Height
clientTop/Left/Width/Height
getComputedStyle(), or currentStyle in IE


次のコードを画面サイズ毎の想定する初回表示領域が終わる位置に挿入することで、初回表示用のレイアウト(リフロー)を強制的に実行できます。初回表示領域に達するとそれ以上レイアウトは発生しません。ただし、サイドバーなどは考慮されていません。

<script>window.belowFold = window.belowFold || document.body.clientHeight > window.innerHeight;</script>