レンダリング ツリーの構築、レイアウト、ペイント

公開日: 2014 年 3 月 31 日

CSSOM ツリーと DOM ツリーを組み合わせたものがレンダリング ツリーに含まれます。レンダリング ツリーは、各表示要素のレイアウトを計算するために使用され、画面にピクセルをレンダリングするペイント処理の入力になります。レンダリングのパフォーマンスを最適化するには、これらの各ステップを最適化することが必須です。

オブジェクト モデルの構築について説明した前のセクションでは、HTML と CSS の入力をベースに DOM ツリーと CSSOM ツリーを構築しました。ただし、両者はドキュメントを別々の側面から捉えた独立したオブジェクトです。一方はコンテンツを記述し、もう一方はドキュメントに適用するスタイルルールを記述します。この 2 つを結合してブラウザの画面上にピクセルをレンダリングするにはどうすればよいでしょうか。

概要

  • DOM ツリーと CSSOM ツリーが組み合わされて、レンダリング ツリーを形成します。
  • レンダリング ツリーにはページのレンダリングに必要なノードのみが含まれています。
  • レイアウトでは各オブジェクトの正確な位置とサイズを計算します。
  • 最後のステップはペイントです。これは最終的なレンダリング ツリーを取り込み、画面にピクセルをレンダリングします。

まず、ブラウザは DOM と CSSOM を組み合わせて「レンダリング ツリー」を作成します。この関数では、ページに表示されるすべての DOM コンテンツと、各ノードのすべての CSSOM スタイル情報が取り込まれます。

DOM と CSSOM を組み合わせてレンダリング ツリーを作成する

レンダリング ツリーを作成するため、ブラウザでは概ね次の処理を行います。

  1. DOM ツリーのルートから順に、表示されている各ノードを走査します。

    • 一部のノード(スクリプトタグ、メタタグなど)は表示されることがなく、レンダリング出力に反映されないので省略されます。
    • 一部のノードは CSS を使用して非表示になり、レンダリング ツリーからも省略されます。たとえば、上記の例では、「display: none」を設定する明示的なルールがあるため、スパンノードがレンダリング ツリーに表示されません。プロパティです。
  2. 表示されるノードごとに、一致する適切な CSSOM ルールを見つけて適用します。

  3. コンテンツとそれぞれの計算されたスタイルを含む可視ノードを出力する。

最終出力は、画面に表示されているすべてのコンテンツのコンテンツとスタイル情報の両方を含むレンダリング ツリーです。レンダリング ツリーが正しく構築されたら、「レイアウト」段階に進むことができます。

ここまでで、表示するノードとその計算されたスタイルを計算しましたが、デバイスのビューポート内の正確な位置とサイズを計算していません。これが「レイアウト」です。「リフロー」とも呼ばれます。

ページ上の各オブジェクトの正確なサイズと位置を把握するため、ブラウザはレンダリング ツリーのルートから順に走査します。次の例を考えてみましょう。

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Critial Path: Hello world!</title>
  </head>
  <body>
    <div style="width: 50%">
      <div style="width: 50%">Hello world!</div>
    </div>
  </body>
</html>

試してみる

上の例の <body> には、ネストされた 2 つの <div> があります。1 つ目(親)の <div> はノードの表示サイズをビューポートの幅の 50% に設定し、2 つ目(子)の <div> は親の 50%(ビューポートの幅の 25%)に width を設定します。

レイアウト情報の計算

レイアウト プロセスの出力は「ボックスモデル」です。は、ビューポート内の各要素の正確な位置とサイズを正確にキャプチャします。相対測定値はすべて、画面上の絶対ピクセルに変換されます。

どのノードが表示されるか、またそのノードで計算されたスタイルとジオメトリがわかったので、この情報を最終ステージに渡し、レンダリング ツリー内の各ノードを画面上の実際のピクセルに変換します。このステップは「ペインティング」とも呼ばれます。「ラスタライズ」と呼ばれます

ブラウザが大量の処理を行うため、時間がかかることがあります。しかし、Chrome DevTools を利用すると、上述の 3 段階すべての分析情報を得ることができます。元の「Hello World」の例で、レイアウト段階について見てみましょう。

DevTools でのレイアウトの測定

  • 「レイアウト」イベントは、タイムラインでのレンダー ツリーの構成、位置、サイズの計算をキャプチャします。
  • レイアウトが完了すると、ブラウザは「Paint Setup」 イベントと「Paint」イベントを発行し、レンダリング ツリーが画面上のピクセルに変換されます。

レンダリング ツリーの作成、レイアウト、ペイントに必要な時間は、ドキュメントのサイズ、適用されたスタイル、実行されているデバイスによって異なります。ドキュメントが大きいほど、ブラウザの作業量は多くなります。スタイルが複雑になればなるほど、ペイントにかかる時間も長くなります(たとえば、単色はペイントに「負荷が低い」のに対し、ドロップシャドウは計算とレンダリングに「負荷が高い」)。

ページがついにビューポートに表示されます。

Hello World ページがレンダリングされました

以下に、ブラウザで行われた手順を簡単にまとめます。

  1. HTML マークアップを処理して DOM ツリーを構築する。
  2. CSS マークアップを処理して CSSOM ツリーを構築する
  3. DOM と CSSOM を組み合わせてレンダリング ツリーを作成します。
  4. レンダリング ツリーでレイアウトを実行して各ノードの形状を計算する。
  5. 個々のノードを画面にペイントします。

このデモページはシンプルに見えるかもしれませんが、ブラウザ側でかなりの処理が必要です。DOM または CSSOM が変更された場合は、画面上に再レンダリングする必要があるピクセルを特定するため、このプロセスを繰り返す必要があります。

クリティカル レンダリング パスの最適化とは、上記の手順 1~5 の合計所要時間を最小限に抑えるプロセスです。その結果、できるだけ短時間で画面にコンテンツをレンダリングできるようになり、初回レンダリング後の画面の更新間隔も短くなります。つまり、インタラクティブなコンテンツの場合に、高いリフレッシュ レートを実現できます。

フィードバック