概要webサービスを公開するにあったて必ず使われることになるのがブラウザです。ブラウザがユーザーにwebページを表示する仕組みを理解することで、フロントエンド開発に役立てたり、ページ表示までのレスポンスの改善などに役立てていきたいと思い、今回ブラウザのレンダリングの仕組みの基本事項についてまとめました。レンダリングの流れ-![レンダリングの流れ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274080/c556d1a2-4e66-4a1f-d589-f2c2e6cc8cd2.png)+ユーザーがwebブラウザにURLを入力すると、ブラウザはURLを元に指定のサーバーにTCP/IPプロトコルに基づいてリクエストを送ります。その後サーバはクライアントに対してレスポンスします。以降のレスポンスとして受け取るHTML,CSS,Javascriptをどう処理して画面に表示するのかをレンダリングと定義して、その処理の流れについてみていきます。pathと呼ばれています)+![progressive-rendering.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274080/0f378229-031d-7314-a828-4e9945530fb8.png)-ブラウザがWebページをレンダリングする仕組みは上のような一連の流れになっています。以下でその一つ一つの工程の内容をみていきます。レンダリングエンジンとJavaScriptエンジン-各工程をみる前に、ブラウザの構成要素をみていきます。-ブラウザにはレンダリングエンジンとJavaScriptエンジンという2つのエンジンが動作しています。+https://developers.google.com/web/fundamentals/performance/critical-rendering-path-**レンダリングエンジン**-HTMLやCSSなどを解析し、実際の画面に描画するためのもの。-レンダリングエンジンによってHTMLやCSSの解釈に差があるためデザインがブラウザによって崩れるという問題があります。+![レンダリングの流れ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274080/8db46249-aa8b-eb64-e0ba-0d109f555235.png)-**JavaScriptエンジン**-JavaScriptを実行するためのエンジン。Edgeの新しいversion(Chromiumベース)が来年の1月15日にリリース予定です。リソースのダウンロード-ブラウザにURLが与えられると、ブラウザは画面のレンダリングに必要なリソース(HTMLやCSSファイル、JavaScriptファイルや画像ファイルなど)を読み込み始めます。--リソースは通常サーバ上に保存されていて、TCP/IPプロトコルを用いてブラウザはサーバーにリクエストしてレスポンスとしてリソースを受け取ります。+ブラウザがWebページをレンダリングする仕組みは上のような一連の流れになっています。以下でその一つ一つの工程の内容をみていきます。オブジェクトモデルの構築-ブラウザではレンダリングを行うために取得したリソースから「オブジェクトモデル」と呼ばれるものを構築します。この時、HTMLはDOMに、CSSはCSSOMに変換されます。-以下の図のように、+ブラウザはページを描画する前に、DOMとCSSOMツリーを構築する必要があります。+このDOMとCSSOMツリーを構築する工程は「オブジェクト構築モデル」といいます。+バイト→文字列→トークン→ノード→オブジェクトモデル(DOM/CSSOM)という流れでオブジェクトモデルは構築されます。standard](https://html.spec.whatwg.org/multipage/)によって決められています)。-+取得した文字列をトークンに変換します。standard](https://html.spec.whatwg.org/multipage/)によって規則が定められています。字句解析-トークンはプロパティとルールを定義するオブジェクトに変換されます。+トークンは\<html>や\<head>といったオブジェクトに変換されます。DOMの構築-オブジェクトはツリー構造にリンクされます。このツリー構造はオリジナルのマークアップの親子関係をそのまま保持します。HTMLオブジェクトはbodyオブジェクトの親であり、bodyは\<p>オブジェクトの親であるという関係になります。ブラウザでは以降このページを処理する際に必ずこのDOMを使用します。-ブラウザはHTMLを処理する度に上のDOM構築の一連の流れを全て行うため処理するHTMLが多い場合は一連のプロセスに時間がかかりボトルネックになってしまいます。+字句解析で作られたオブジェクトはオリジナルのマークアップの定義に基づいた親子関係をもつ木構造に整形されます。+\<html>オブジェクトは\<body>オブジェクトの親で、\<body>は\<p>の親でといったようなHTMLのマークアップでみる構成になります。++この最後のプロセスの最終的な成果物が描画するページのDOMとなります。-ページのライフサイクルイベントのDOMContentLoadedはDOMツリーの構築が完了した時点でレンダリングエンジンにより発火されます。そのためDOMContentLoadedイベントの時点では画像やCSSは読み込まれていない可能性があります。同じライサイクルであるloadイベントは画像やCSSなどを含む全てのリソースを読み込んだ時点で発火します。CSSOMツリーの構築![cssom-tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274080/a3019e6b-676c-270f-ae96-b67dd573721c.png)ブラウザでDOMを構築している際にドキュメントのheadタグで外部のcssスタイルシートを参照しているlinkタグに遭遇すると、ブラウザはページのレンダリングにこのリソースが必要であると想定してこのリソースに対するリクエストを即座にディスパッチし、CSSのパースを行います。HTMLと同様にバイトが文字列、トークン、ノードに変換され最終的にCSSOMツリーを構築します。DOMツリーとCSSOMツリーはそれぞれ独立しており後の工程で出てくるレンダリングツリーによってリンクされます。各種リソースを読み込んだ後は、JavaScriptエンジンによってJavaScriptのコードが解析、実行されます。JavaScriptのコードが字句解析されトークンとなり、次に構文解析され抽象構文木となり、最後にコンパイルされて実行可能なファイルとなり実行されます。レンダリングツリーの構築コンテンツを記述したDOMツリーとドキュメントに適用するスタイルルールを記述したCSSOMツリーを結合することでレンダリングツリーを構築する必要があります。レンダリングツリーは各表示要素のレイアウトを計算するために使用され、画面にピクセルをレンダリングするペイント処理の入力となります。レンダリングツリー構築の手順として、DOMツリーの各要素に対してどのCSSプロパティがマッチするかを計算します。CSSのルールセットにはh1やpのようなCSSセレクタと、widthやcolorのようなCSSプロパティがあり、最初にCSSセレクタによってDOMツリーの要素とCSSルールのマッチングを行います。その後、各DOM要素にどのCSSプロパティがマッチングするかを計算します。CSSセレクタのマッチンングレンダリングエンジンはCSSセレクタを右側から順に評価していきます。CSSプロパティのマッチングどのCSSプロパティがDOM要素に適用されるかをレンダリングエンジンが決定するための詳細度という仕組みがあります。Cとなっていて1つでも上位レベルが含まれる場合はそれが優先され、同じレベルでは値が大きい方が優先されます。`color:red`の方が優先されます。詳細度が同じ場合は後に定義されたCSSルールセットが適用されますそのため上の例の`#id`の要素には`font-size:30px`が適用されます。レンダリングツリーのレイアウトレイアウトの工程では端末ビューボード内での各ノードのレイアウト情報を算出しますレイアウト情報には要素の大きさやmargin/padding、x/y/z軸の位置などが含まれます。レンダリングエンジンはレンダリングツリーのルート要素から順番に各要素が持つCSSプロパティを元にレイアウト情報を決めていきます。world!</div></div></body></html>```上のようなHTMLの場合、`viewport`がデバイスのサイズで倍率が1倍ということに決まります。ネストされた2つのdivがあり、1つ目のdivがviewportの幅の50%になり、2つ目のネストしたdivの幅は親のdivの50%(全体の25%)になります。レンダリングツリーの描画webページの描画にはペイントとコンポジットの2つの工程があります。ペイント各レイヤごとにテキストや色、画像などをピクセルに書き込みます。ピクセルへの書き込みの2つの工程からなります。前の手順で構築したレンダリングツリーを元にグラフィックエンジンのための命令リストを作成します。命令リストでは「どのピクセルに何色を入れるのか」という命令が入っているため、その命令を元にグラフィックエンジンがピクセルの描画を行います。次にピクセルの書き込みを行います(ラスタライゼーション)。ピクセルの書き込みはレイヤ単位で行われ、position:abosolute;やopacityといったCSSプロパティなどz軸を考慮する必要のある要素が存在する場合は新しいレイヤが作成されます。コンポジットピクセルを書き出したレイヤを合成してレンダリング結果を出力します。レンダリングエンジンとJavaScriptエンジン+ブラウザにはレンダリングエンジンとJavaScriptエンジンという2つのエンジンが動作しています。++**レンダリングエンジン**+HTMLやCSSなどを解析し、実際の画面に描画するためのもの。+レンダリングエンジンによってHTMLやCSSの解釈に差があるためデザインがブラウザによって崩れるという問題があります。++**JavaScriptエンジン**+JavaScriptを実行するためのエンジン。Edgeの新しいversion(Chromiumベース)が来年の1月15日にリリース予定です。まとめブラウザレンダリングの仕組みを各工程ごとにみることで、ページライフサイクルのイベントがどの工程で発生するのかをきちんと理解できるようになりました。レンダリングの仕組みの知識を元に、ブラウザの開発ツールを駆使して開発時にデバッグやパフォーマンスのボトルネックの分析、改善に役立てていきたいと思います。