【実務・中級編】 DOMツリー構築とスクリプトのブロッキング – Webブラウザの仕組み実践ガイド

やあ。今日もどこかのコードレビューで「なんでこんなところに`script`タグ置いてるんだよ……」と頭を抱えているところかい?

フロントエンドをやっていると、画面が真っ白なまま数秒間固まる「ホワイトスクリーン問題」に一度は直面するはずだ。ユーザーが離脱する魔の数秒間。その犯人の多くは、DOM構築の裏側でこっそり悪さをしているJavaScriptのブロッキング挙動にある。

今回は、ブラウザがHTMLをどう読み、なぜJSがパースを止めてしまうのか、そしてそれをどうスマートに回避するのかについて、現場の知見を交えて徹底的に解説していこう。

—

1. HTMLパースの裏側:ブラウザのメインスレッドは超多忙

まず大前提として、Webブラウザのメインスレッドは基本的にシングルスレッドで動いている。HTMLのパース、CSSOMの構築、JavaScriptの実行、レイアウト計算、ペイント(描画)……これらすべてを、あの限られたシングルスレッドの上で時分割で処理しているんだ。

ブラウザがサーバーからHTMLを受け取ると、ネットワーク層からストリーミングされてくるバイトデータを「HTMLパーサー」に流し込む。このパースの基本方針は「インクリメンタル(逐次処理)」だ。つまり、HTMLの先頭から順に文字を読み込み、トークナイザーがタグを認識した瞬間に、上から下へ向かってDOM(Document Object Model)ツリーをコツコツと組み立てていく。

[HTMLバイトデータ]
↓
[トークナイザー]
↓
[DOMツリー構築] ← ここにインクリメンタルにノードが追加されていく

ユーザービリティの観点から言えば、このツリーが少しずつ構築されるにつれて、ブラウザは画面をチラ見せ(漸進的レンダリング)させたいわけだ。しかし、ここに「あいつ」が割り込んでくると、すべてが台無しになる。そう、`


こんにちは、世界


良い例:`defer` とモジュールを活用したモダンな構成





最適化された例







プロダクト名





ここで一つ、シニアとして現場のメンバーに伝えておきたい豆知識がある。ES Modulesの `type="module"` を指定したスクリプトは、デフォルトで `defer` と同じ非同期・遅延実行の挙動になる仕様だ。だから、モジュールベースでコードを書いている現代のViteやWebpack(近代的な設定)の成果物は、基本的にパースをブロックしない優れものになっている。しかし、レガシーなサードパーティ製スクリプトや、ボディの途中にベタ書きされた古典的なコードには依然として注意が必要だ。

---

5. まとめ:ブラウザと対話するフロントエンドエンジニアへ

Webブラウザは、私たちが書いたコードを上から順に、時に忠実に、時に融通を利かせながら必死に解釈して画面に映し出している。

DOMツリーの構築とスクリプトのブロッキングの関係を理解することは、単なる「表示速度の高速化(SEO対策やCore Web Vitalsの改善)」にとどまらず、「ブラウザのメインスレッドをいかに解放し、ユーザー体験を滑らかにするか」というフロントエンドエンジニアとしての本質的な腕の見せ所だ。

「なぜここで画面が止まるのか?」と疑問に思ったときは、Chrome DevToolsの「Performance」タブを開き、Mainスレッドのタイムラインでパーサーがどこでブロックされているかを自分の目で確かめてほしい。数字や仕様書をただ覚えるよりも、圧倒的に深い知見として君の血肉になるはずだ。

さあ、明日からのコードでは、不要な場所にある `

シェアする
frontendintronationalをフォローする

コメント

タイトルとURLをコピーしました