Webページ高速化に必須の知識!ブラウザがWebページをどのようにレンダリングしているか、図を用いて解説
Post on:2020年11月12日
ブラウザがWebページをどのようにレンダリングしているか、図を用いてやさしく解説した記事を紹介します。
レンダリングの仕組みを理解することで、HTMLやCSSやJavaScriptなど実装時にも気をつける点があります。
How the browser renders a web page
by James Starkie
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- はじめに
- 1. HTMLの解析(パース)を開始する
- 2. 外部リソースを取得する
- 3. CSSを解析し、CSSOMを構築する
- 4. JavaScriptを実行する
- 5. DOMとCSSOMをマージしてレンダリングツリーを構築する
- 6. レイアウトとペイントを計算する
はじめに
私の考えとしては、高速で信頼性の高いWebサイトを構築するには、実装中に各ステップを最適化できるようにブラウザがWebページをレンダリングするメカニズムを理解する必要があります。この記事では、ハイレベルのエンドツーエンドでのプロセスに関する私の学びをまとめたものです。
この記事での知見の多くは、UdacityのWebsite Performance Optimization(Webサイトのパフォーマンス最適化)コースに基づいています。無料ですので、ぜひチェックしてみてください。
また、How Browsers Work: Behind the scenes of modern web browsers(ブラウザの仕組み: モダンブラウザの舞台裏)という記事も非常に参考になりました。2011年の記事ですが、この記事を書いている時点でも、ブラウザの動作の基本的な部分の多くは関連しています。
ブラウザがWebページをどのようにレンダリングしているか、このプロセスは6つのステップに分けることができます。
1. HTMLの解析(パース)を開始する
ブラウザがネットワーク経由でページのHTMLデータの受信を開始すると、ブラウザはすぐにパーサーを設定して、HTMLをドキュメントオブジェクトモデル(DOM)に変換します。
ドキュメントオブジェクトモデル(DOM)とは、Web上のドキュメントの構造と内容を構成するオブジェクトをデータで表現したものです。
この解析(パース)処理の最初のステップは、HTMLを開始タグと終了タグ、およびコンテンツを表すトークンに分解します。それらからDOMが構築されます。
ブラウザはHTMLを解析(パース)して、DOMを構築
2. 外部リソースを取得する
パーサーがCSSやJavaScriptファイルなど、外部リソースを見つけると、それらのファイルを取得するためにパーサーが停止します。パーサーはCSSファイルが読み込まれる間も続行されますが、読み込まれて解析されるまでレンダリングはブロックされます(詳細は後述します)。
JavaScriptファイルはCSSとは少し異なります。
デフォルトでは、JavaScriptファイルが読み込まれて解析される間、HTMLの解析はブロックされます。これを軽減するためにscriptタグに追加できる属性は、deferとasyncの2つです。どちらもJavaScriptファイルがバックグラウンドで読み込まれている間にパーサーを継続させることができますが、実行方法が異なります。これについても詳しく説明しますが、要約すると下記のようになります。
deferは、ドキュメントの解析が完了するまでファイルの実行を遅らせることを意味します。複数のファイルにdefer属性がある場合は、HTMLで検出された順番で実行されます。
1 |
<script type="text/javascript" src="script.js" defer> |
asyncは、ファイルが読み込まれるとすぐに実行することを意味します。これは解析プロセス中またはプロセス後に発生する可能性があるため、非同期スクリプトの実行順序を保証することはできません。
1 |
<script type="text/javascript" src="script.js" async> |
リソースのプリロード
余談ですが、モダンブラウザはブロックされている間もHTMLをスキャンし続け、どのような外部リソースがあるか「先読み」して、推測的にダウンロードします。この方法はブラウザによって異なるため、特定の方法で動作するとは限りません。リソースを重要なものとしてマークし、レンダリングプロセスの早い段階でダウンロードされる可能性を高めるために、rel="preload"をlinkタグに使用することができます。
1 |
<link href="style.css" rel="preload" as="style" /> |
外部リソースの取得はCSSとJavaScriptで少し異なる
3. CSSを解析し、CSSOMを構築する
DOMという言葉は聞いたことがあるかもしれませんが、CSSオブジェクトモデル(CSSOM)という言葉は聞いたことがありますか?
私はこの記事のために調べる前は、知りませんでした。
CSSオブジェクトモデル(CSSOM)は、すべてのCSSセレクタと各セレクタに関連するプロパティをツリー状にマップしたもので、ルートノード、兄弟、子孫、子、およびその他の関係を持ちます。CSSOMはドキュメントオブジェクトモデル(DOM)と非常によく似ています。両方とも、Webサイトを適切にレンダリングするために必要な一連のステップであるクリティカル レンダリング パス(Critical Rendering Path)の一部です。
CSSOMはDOMとともに、ブラウザがWebページのレイアウトとペイントに使用するレンダリングツリーを構築します。
HTMLファイルやDOMと同様に、CSSファイルが読み込まれると、それらのファイルは解析され、ツリーに変換されなければなりません。ページ上のすべてのCSSセレクタ、それらの階層、それらのプロパティが記述されます。
CSSOMがDOMと異なる点は、CSSのルールは詳細度により上書きされてしまう可能性があるため、CSSOMを段階的に構築することができないことです。すべてのCSSが解析されてCSSOMが構築されるまでは、ブラウザは各要素がどのようにスタイルされ、配置されるか知ることができません。CSSがレンダリングをブロックするのはこれが原因です。
CSSは上書きされる可能性があるため、すべてのCSSが解析されてから構築される
4. JavaScriptを実行する
JavaScriptリソースがいつどのように読み込まれるかによって、いつどのように起こるかが決まりますが、ある時点でJavaScriptリソースは解析・コンパイル・実行されます。ブラウザが異なれば、これらのタスクを実行するためのJavaScriptエンジンも異なります。
JavaScriptの解析は、他のタイプのリソースよりもコンピューターのリソースの観点から負荷のかかるプロセスになる可能性があり(JavaScript Start-up Performance)、そのため、JavaScriptを最適化することが優れたパフォーマンスを実現するために非常に重要である理由です。JavaScriptエンジンがどのように機能するかについては、この素晴らしい記事が参考になります。
翻訳版: JavaScriptエンジンの仕組みをGIFアニメで分かりやすく解説
イベントの読み込み
同期的にロードされたJavaScriptとDOMが完全に解析されて準備が整うと、document.DOMContentLoadedイベントが発生します。DOMへのアクセスを必要とするスクリプトの場合、例えば何らかの方法でDOMを操作したり、ユーザーインタラクションのイベントをする場合は、スクリプトを実行する前にまずこのイベントを待つことをお勧めします。
1 2 3 |
document.addEventListener('DOMContentLoaded', (event) => { // You can now safely access the DOM }); |
非同期のJavaScriptや画像などの読み込みが完了すると、windwo.loadイベントが発生します。
1 2 3 |
window.addEventListener('load', (event) => { // The page has now fully loaded }); |
JavaScriptの解析は負荷がかかるため、最適化することが非常に重要
5. DOMとCSSOMをマージしてレンダリングツリーを構築する
レンダリングツリーとはDOMとCSSOMの組み合わせで、ページにレンダリングされるすべてのものを表します。ただし、レンダリングツリー内のすべてのノードが視覚的に存在することを意味するものではありません。例えば、opacity: 0;やvisibility: hidden;のノードはスクリーンリーダーなどでは読み取られる可能性はありますが、display: none;のノードには何も含まれません。さらに視覚的な情報を含まない<head>のようなタグは常に省略されます。
JavaScriptエンジンと同様に、ブラウザが異なればレンダリングエンジンも異なります。
視覚的な情報を含まない要素はレンダリングツリーから除外される
6. レイアウトとペイントを計算する
これで完全なレンダリング ツリーができたので、ブラウザは何をレンダリングするかを認識しますが、どこにレンダリングするかは認識していません。そのため、ページのレイアウト(つまり、すべてのノードの位置とサイズ)を計算する必要があります。レンダリングエンジンはレンダリングツリーを走査して、上部から下部に向かって各ノードが表示されるべき座標を計算します。
計算が完了すると、最後のステップはそのレイアウト情報を取得し、スクリーンにピクセルをペイントすることです。
これで完成です!
完全にレンダリングされたWebページが完成します。
レイアウト(すべてのノードの位置とサイズ)を計算して、スクリーンにピクセルをペイントする
sponsors