1. はじめに
この記事では、Webページが読み込まれる際、HTMLが分割されて段階的にパースされる様子を観察します。
2. 前提知識
- (HTML)パースは、HTMLを読み込んでDOMツリーという「HTML要素から構成される木構造」を構築する処理を指します。
- これとは別に、CSSを元に CSSOMツリーが構築されます(装飾を担当)。
- DOMツリーとCSSOMツリーから、レンダリングツリーが構築されます。
- レンダリングツリーができた上で、画面のレイアウトやレンダリングが行なわれ、画面にWebページが表示されます。
- HTMLファイルの途中までの情報を元にしても、以上の処理を行うことができます。
以下の記事も参考にしてください。
3. 方法
Chrome ブラウザのデベロッパーツール (DevTools) が備えている [Performance] パネルで、Webページの読み込み処理を解析させ、その結果を観察します。
4. 解析した結果を観察する
とあるWebページを、[Performance] パネルで解析しましたので、その結果を紹介します。
まず、このWebページのHTMLファイルは、654行あります(下画像参照)。
ここから、[Performance]パネルで行った解析の結果画面を載せていきます。
※ 横軸は時間で、左から右に時間が進みます。
画面中央左端あたりの青い四角の部分で、HTMLファイルが読み込まれています。そこから下の部分では、Mainスレッドで実行された処理が時系列で表示されています。赤枠で囲われた部分が1回目のパース処理です(このとき、この部分を選択状態にしていたので赤枠がついています)。ここの詳細情報が画面の下側で表示されているのですが、先頭に「Parse HTML」という表示があるので、HTMLをパースしていることが分かります。そして、下の方の Range の部分に [0…103] とあるのは、HTMLファイルの0行目から103行目までをパースしたことを意味しています(1からではなく、0からカウントしているようです)。
この赤枠のすぐ下の部分では、パース中に見つかったCSSファイルやJavaScriptファイルを取得するためにリクエストを送信している四角があります(細すぎてこの画像では分かりづらいと思います)。画像の中央まで視線を上げると、そのあたりで紫の四角 (CSSファイル)、オレンジの四角 (JavaScriptファイル) が現れているのはそのためです。
次の画像(上の画像です)では、赤枠が右の方に移動しました。ここが 2回目のHTMLパース処理です。Range の行では [104…365] とあり、104行目から365行目までをパースしていることが分かります。
3回目のHTMLパースでは、Range の部分が [366…365] というおかしな数字になっています。ここで赤枠のすぐ右側を見ると、しばらく何も処理が行なわれていません。恐らくですが、ここでは既にリクエストを送信したCSSファイル (紫色) が取得され、CSSOMが構築されるのを待っているのだと思われます。CSSファイルをリクエストすると、そのファイルを取得してその時点でのCSSOMが構築されるまで、レンダリング処理がブロックされるためです(CSSOMがないとレンダリングツリーが構築できないため。レンダリングツリーがないとレンダリングができません)。このとき、ブラウザはここまでのHTMLとCSSで一旦レンダリングまで行うことがユーザーから見て有益であると判断した可能性があります。というわけで、HTMLパースの終了地点を365行目に戻すことにより、次回は再度366行目から再開できることになります。
4回目では、366行目から613行目までをパースしています。
5回目にして、ようやくHTMLファイルの最後の行までパースされました (最後の行は閉じタグなので行数として表示されていないのだと思われます)。
HTMLパースにより、この時点で一旦 DOMツリーが完成されていますが、この後、JavaScript が実行されるため、JavaScriptの処理によってDOMツリーが操作される可能性があります。変更された場合は、その部分だけパース処理が行なわれます。
ということで、HTMLが分割されてパースされる様子を観察しました。
5. おわりに
Chrome のデベロッパーツールはどなたでも使えますので、是非お好みのWebページで [Performance] パネルでの解析を行ってみてください。