ブラウザのレンダリングの大まかな流れ
- Loading
- Scriping
- Rendering
- Painting
Loading
リソース読み込みの処理。
与えられたURLからHTMLを読み込んで、そこからさらにレンダリングに必要な付属するリソースを読み込んで解釈する、
大きく分けると2つフェーズがある
1. リソースのダウンロード
2. リソースのパース
リソースのダウンロード
HTML自身を含むリソースをサーバーからダウンロード。
リソースのパース
ダウンロードしたリソースを構文解析して、レンダリングエンジンの内部表現に変換する。
HTML読み込み
読み込んだHTMLは解釈してドキュメントのDOMツリーを構築する
DOM=HTMLのドキュメントを表現するオブジェクト
DOMツリー=レンダリングエンジンが利用する木構造持つ内部表現
以下の工程を経てDOMツリーへ変換される
1. 字句解析によるトークンのリスト化
2. 構文解析による構文木の構築
3. 構文木内にあるJavaScriptを実行しつつDOMツリーの構築
CSSの読み込み
DOMツリーに対して、要素を指定するCSSセレクタと、それらに適用するCSSプロパティと値の組を宣言する。
読み込まれたCSSは、レンダリングエンジンんによってパースされてCSSOMツリーへ変換される。
Scriping
レンダリングエンジンは、JavaScriptのコードをJavaScriptエンジンに引き渡して実行させる。
JavaScriptの実行の流れの以下で実行される
1. 字句解析(コードをトークン列に変換)
2. 構文解析(トークン列を抽象構文木に変換)
3. コンパイル(抽象構文木を実行可能コードに変換)
4. 実行
字句解析と構文解析
トークン列とは、ラベルつけしをした文字列のリスト。
抽象構文木とはJavaScriptの文法に沿った形で表現される木構造のデータ
コンパイル
抽象構文木を実行可能コードに変換する。変換の流れは、JavaScriptエンジンの実装に依存。
実行
JavaScriptのコードは、処理系内部の仮想マシン、もしくはCPUで実行される。
Rendering
レイアウトツリー構築をする。
構築のなで
1. スタイルの計算
2. レイアウト
の処理おこなれる
スタイルの計算
ドキュメントのDOMツリー内の全てのDOM要素に対して、同様なCSSプロパティが当たるのかを計算する。
CSSOMツリー内を全て参照して、CSSルールのCSSセレクタのマッチング処理がこの時に行われる。全てのDOM要素に対して、CSSルールのCSSセレクタがマッチするかを総当たりで試行する。
レンダリングエンジンはセレクタを右から左に解釈してマッチング処理を行う。
CSSセレクタによって詳細を調べる方法
https://specificity.keegan.st/
レイアウト
DOMツリー内の全てのノードの視覚的なレイアウト情報の計算する
- 要素の大きさ
- 要素のマージン
- 要素のパディング
- 要素の位置
- 要素のz軸の位置
など
Painting
レンダリング結果の描画をおこなれる。主に3つの処理
1. ペイント
2. ラスタライズ
3. レイヤーの合成
ペイント
内部の低レベルな2Dグラフィックエンジン向けの命令を生成。
ラスタライズ
生成された命令を用いて実際にピクセルへと描画する。この時、レイヤーという単位で一枚一枚描画される。
レイヤーが生成されるのか、ある要素が次のような条件にある場合
- 要素がposition: absoluteなスタイルプロパティが適用されている
- 要素がposition: fixedなスタイルプロパティが適用されている
- 要素がtransform: translate3dなどのGPUで描画・合成されるCSSプロパティを持っている
- 要素にopacityCSSプロパティが適用されており、透過して背後のコンテンツが表示される必要がある
レイヤーの合成
ピクセルにしたレイヤーを合成して最終的なレンダリング結果を生成する。
この合成処理は、CPUによる合成とGPUによる合成がある
再レンダリング
全てを最初から行うのではなく、構築した内部表現のオブジェクトをなるべく再利用しようとする。
一部のフェーズのみの再実行する場合もあれば、複数の場合も。