サイトのパフォーマンス改善で重要なクリティカル レンダリング パスについて
Post on:2017年2月21日
ブラウザがページを表示する際にサーバーからHTMLのレスポンスを受け取ると、スクリーンにピクセルが描画されるまでに多くのステップが必要になります。ブラウザがページの最初のペイントを実行するために必要とするこのシーケンスは「クリティカル レンダリング パス(Critical Rendering Path)」と呼ばれます。
クリティカル レンダリング パスを理解することで、サイトのパフォーマンスを改善するのに役立ちます。
Understanding the Critical Rendering Path
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
クリティカル レンダリング パス(Critical Rendering Path)には、6つの段階があります。
クリティカル レンダリング パスの6つの段階
- 01. DOMツリーの構築
- 02. CSSOMツリーの構築
- 03. JavaScriptの実行
- 04. レンダリング ツリーの作成
- 05. レイアウトの生成
- 06. ペインティング
- クリティカル レンダリング パスを調べる
01. DOMツリーの構築
DOM(Document Object Model)ツリーとは、パースされたHTMLのドキュメントをツリー構造として表現したものです。ルート要素である<html>から始まり、ページ上のあらゆる要素やテキストごとにノードが作成されます。他の要素にネストされた要素は子ノードとして表現され、各ノードにはその要素の属性すべてが含まれます。例えば、<a>要素はそのノードに関連づけられたhref属性を持ちます。
下記のコードでDOMツリーを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<html> <head> <title>Understanding the Critical Rendering Path</title> <link rel="stylesheet" href="style.css"> </head> <body> <header> <h1>Understanding the Critical Rendering Path</h1> </header> <main> <h2>Introduction</h2> <p>Lorem ipsum dolor sit amet</p> </main> <footer> <small>Copyright 2017</small> </footer> </body> </html> |
DOMツリーは、下記のようになります。
サンプルのHTMLのDOMツリー
HTMLの良い点は、部分的に実行できることです。ページにコンテンツが表示されるには、完全なドキュメントを読み込む必要はありません。しかし、他のリソース、CSSとJavaScriptがページのレンダリングをブロックする可能性があります。
02. CSSOMツリーの構築
CSSOM(CSS Object Model)とは、DOMに関連付けられたスタイルのオブジェクトを表現したものです。DOMと類似した方法で表現されますが、明示的に宣言されているか暗黙的に継承されているかにかかわらず、各ノードのスタイルが関連づけられて表現されます。
前述のHTMLのstyle.cssファイルには、次のようなスタイルがあります。
1 2 3 4 5 6 7 8 9 |
body { font-size: 18px; } header { color: plum; } h1 { font-size: 28px; } main { color: firebrick; } h2 { font-size: 20px; } footer { display: none; } |
CSSOMツリーは、下記のようになります。
サンプルのCSSOMツリー
CSSは「レンダー ブロッキング リソース(render blocking resource)」と見なされます。これは最初にリソースを完全にパースすることなく、レンダリング ツリー(04. レンダリング ツリーの作成を参照)を構築することができないことを意味します。HTMLとは異なり、カスケードの性質を継承しているため、CSSを部分的に使用することはできません。
ドキュメント内で後に定義されたスタイルは、前に定義されたスタイルを上書きして変更することができます。そのため、スタイルシートのすべてがパースされる前にスタイルシートで前に定義されたCSSのスタイルを使い始めると、間違ったCSSが適用されることがあります。つまり、次の段階に進む前に、CSSを完全にパースする必要があります。
CSSファイルは、現在のデバイスに適用される場合にのみレンダー ブロッキングと見なされます。<link rel = "stylesheet">タグはmedia属性を指定することができ、適用されるスタイルのメディアクエリを指定することができます。例えば、media属性に「orientation: landscape;」を指定した場合、ポートレートモードでページを表示している時にはそのリソースはレンダー ブロッキングとみなされません。
また、CSSは「スクリプト ブロッキング(script blocking)」にもなります。これは、JavaScriptファイルは実行される前にCSSOMが構築されるまで、待機する必要があるからです。
03. JavaScriptの実行
JavaScriptは「パーサ ブロッキング リソース(parser blocking resource)」と見なされます。これは、HTMLドキュメント自体をパースすることがJavaScriptによってブロックされるからです。
パーサーが<script>タグに到達すると、そのスクリプトが内部か外部かに関係なく、取得して(外部の場合)実行します。そのため、ドキュメント内の要素を参照するJavaScriptファイルがある場合は、そのドキュメントを記述した後に配置する必要があります。
JavaScriptのパーサ ブロッキングを避けるために、async属性を適用して非同期にロードできます。
1 |
<script async src="script.js"> |
04. レンダリング ツリーの作成
レンダリング ツリーはDOMとCSSOMの両方を組み合わせたもので、ページに最終的に表示される内容を表現するツリーです。このことは目に見えるコンテンツのみを取得し、「display: none;」を使用してCSSで非表示にした要素は含めないということを意味します。
前述のDOMとCSSOMを使用すると、下記のレンダリング ツリーが作成されます。
サンプルのレンダリング ツリー
05. レイアウトの生成
レイアウトはビューポートのサイズを決定するもので、パーセンテージやビューポートの単位に依存するCSSスタイルのコンテキストを提供します。ビューポートのサイズは、head内の<meta name = "viewport">タグによって決まります。タグが指定されていない場合は、デフォルトのビューポート幅である980pxが適用されます。
例えば、最も一般的な<meta name = "viewport">の値は、デバイスの幅に対応するようにビューポートサイズを設定することです。
1 |
<meta name="viewport" content="width=device-width,initial-scale=1"> |
もしユーザーが幅1000pxのデバイスでWebページにアクセスした場合、サイズはその単位に基づいて決まります。ビューポートの半分は500pxで、10vwは100pxになります。
06. ペインティング
最後の段階はペインティング(Painting)で、ページの目に見えるコンテンツをピクセルに変換して、スクリーンに表示します。
ペインティングにかかる時間は、DOMのサイズや適用されるスタイルによって異なります。いくつかのスタイルは、他のスタイルよりも多くの作業を実行する必要があります。例えば、複雑なグラデーションの背景画像は、単色の背景色よりも時間がかかります。
クリティカル レンダリング パスを調べる
クリティカルレンダリングパスを調べるのは、Chromeのデベロッパーツールで調べることができます。「Timeline」タブにあります(CanaryではPerformanceに改名)。
例えば、前述のサンプル(<script>タグを追加しました)を見てましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<html> <head> <title>Understanding the Critical Rendering Path</title> <link rel="stylesheet" href="style.css"> </head> <body> <header> <h1>Understanding the Critical Rendering Path</h1> </header> <main> <h2>Introduction</h2> <p>Lorem ipsum dolor sit amet</p> </main> <footer> <small>Copyright 2017</small> </footer> <script src="main.js"></script> </body> </html> |
ページロードのイベントログを見ると、下記が表示されます。
サンプルのタイムライン
-
- Send Request
- index.htmlに対してGETのリクエストを送信
-
- Parse HTML, Send Request
- HTMLとDOM構造のパースを開始。 style.cssとmain.jsのGETリクエストを送信。
-
- Parse Stylesheet
- style.cssによってCSSOMが作成。
-
- Evaluate Script
- main.jsを評価。
-
- Layout
- HTMLの<meta name = "viewport">タグに基づいてレイアウトを生成。
-
- Paint
- ドキュメント上のピクセルをペイント。
これらの情報に基づいて、どの段階でロード時間がかかっているのかが判明し、クリティカル レンダリング パスを最適化する方法を決定することができます。
sponsors