Open5

ブラウザレンダリングについて

shhkrshhkr

Loading - リソース読み込み

このフェーズの主な役割は

  • リソースのダウンロード(Download)
  • リソースのパース(Parse)

Download

以下のリソースをサーバーからダウンロード

  • HTMLファイル
  • CSSファイル
  • JavaScriptファイル
  • 画像ファイル(JPEG、PNG、GIF、SVG)

Parse

HTMLをDOMツリー、CSSをCSSOMツリーに変換(レンダリングエンジンが解析できる形式に変換)

HTML読み込み

以下の工程を経てDOMツリーに変換される

  1. HTMLを解析してトークンをリスト化
  2. トークンからツリーデータを作成
  3. ツリーデータにあるJavaScriptを実行しつつDOMツリーの構築
shhkrshhkr

Scripting - Javascript実行

レンダリングエンジンはJavascriptコードを JavaScript エンジンに引き渡して実行する

  1. Javascriptコードを解析しトークンを生成
  2. トークンを解析しASTデータ(抽象構文木)を作成
  3. ツリーデータを実行可能な状態にする
  4. 仮想マシンやCPUで実行される

参考

https://zenn.dev/oreo2990/articles/5b56230ba2d7a1
https://zenn.dev/antez/books/568dd4d86562a1/viewer/09848c
https://engineering.mercari.com/blog/entry/20220128-3a0922eaa4/

shhkrshhkr

3. Rendering - レイアウトツリー構築

Javascriptの実行が終わるとスタイルの計算とレイアウトが行われる

Calculate Style

  • 構築したDOM要素にどのCSSが適用されるか計算
    • この時にCSSOMツリー全てを参照し、全てのDOM要素に対してCSSセレクタのマッチングを総当たりで行う
  • DOM要素にどのCSSが適用されるかが分かれば、CSSの詳細度でどのCSSが適用されるか判別

CSSセレクタのマッチング

  • CSSセレクタのマッチングは総当たりで行う(DOMが100個、CSSが50個ある場合には 100 * 50 = 5000回のマッチング処理が走る)
  • マッチングは右から左へ行われる
    /* 1. DOM要素のclass属性にbuttonが含まれている */
    /* 2. その親要素のclass属性にcontainerが含まれている */
    /* 3. その親要素のDOM要素名がbodyである */
    body .container > .button {
        color: red;
    }
    
  • 詳細度はセレクターの重み分類で判定される(1-0-0, 0-1-0 , 0-0-1のような形式)

Layout

DOM要素に当たるCSSプロパティを判別した後、レンダリングエンジンはDOMツリー内のすべてのノードの視覚的なレイアウト情報の計算する。
レイアウト情報とは、

  • 要素の大きさ
  • 要素のマージン
  • 要素のパディング
  • 要素の位置
  • 要素のz軸の位置
shhkrshhkr

4. Painting - レンダリング結果の描画

Paint

  • グラフィックエンジンに向けた命令を生成

Rasterize

  • 生成された命令を用いて、レンダリングツリー内の各ノードをレイヤー単位でピクセルに変換していく

ブラウザのウィンドウをスクロールするときには、スクロール分だけコンテンツの表示される位置を移動して描画を更新する必要がある
しかし、このとき更新しなければならないのはコンテンツの表示の位置だけで、コンテンツの描画そのものは変更する必要はないため、以前描画したレイヤーがこのとき再利用される

Composite Layers

  • ピクセルにしたレイヤーを合成してレンダリング結果を生成
  • 合成処理はCPUで行われるが、3DなどはGPUで処理される(z軸の処理はGPUの方が早いため)

以上の工程を経て、コンテンツが表示される