初級ではブラウザを「大工さん」と捉えました。中級では、設計図がピクセルになるまでの工程と、ブラウザのセキュリティ境界を見ます。
概要 — まず全体をつかむ
詳細 — 1段階ずつ追う
これは何をする係?
ブラウザは複数のエンジンの集合体です。
- レンダリングエンジン — HTML/CSSを解析して画面を描く
- JSエンジン — JavaScriptを実行する(DOMを操作する)
- ネットワーク/ストレージ — 通信、Cookie・キャッシュ・localStorage の管理
- サンドボックス — タブやサイトを隔離し、悪意あるコードの影響を閉じ込める
登場人物メモ:
- ※1 DOM/CSSOM — HTML/CSSから作られる木構造
- ※2 レンダーツリー — 実際に描くべき要素の木(表示されない要素は除く)
やさしく言うと(初級)
設計図を受け取って建物を建てる大工さんを思い浮かべてください。ブラウザは、送られてきた設計図(※1〜3)を解釈し、あなたの見る画面に組み立てます。
- ※1 HTML — 骨組み(見出し・段落・画像などの構造)
- ※2 CSS — 見た目(色・大きさ・配置の装飾)
- ※3 JS — 動き(ボタンの反応・入力チェックなどの振る舞い)
仕事の流れ(描画パイプライン)
- パース — HTMLから DOM、CSSから CSSOM を作る
- レンダーツリー — 両者を合わせ、描くべきものを決める
- レイアウト — 各要素の位置・大きさを計算する
- ペイント/合成 — ピクセルに変換し、レイヤーを重ねて表示する
- JSが DOM を書き換えると、必要な範囲で リフロー(再計算)/リペイント(再描画) が走る
- JS実行と描画は 単一のメインスレッド を奪い合う(イベントループ)。重いJSが走っている間は描画も入力も止まる=画面が固まる
アニメーション『イベントループ(単一メインスレッド)』を開く
この部分をもっと深く(上級)
中級のパイプライン(パース→レンダーツリー→レイアウト→ペイント→合成)を、性能に効く粒度で見直します。
- HTMLの増分パース — ブラウザはHTMLを最後まで待たず、届いた分から少しずつDOMを組み立てる。さらにプリロードスキャナが本文解析と並行して先読みし、後方の画像やCSSを早めに取りに行く
- レンダーブロッキングなCSS — CSSはCSSOMが完成するまで最初のペイントを止める。CSSが「描画をブロックする資源」と呼ばれるのはこのため。逆にHTMLパースは基本止めない
- レイアウト(リフロー) — 各要素の位置と大きさを幾何計算する。要素数や入れ子が深いほど重い
- ペイント — 塗る内容(色・文字・影)をレイヤーごとのビットマップに変換する
- コンポジット(合成) — 複数のレイヤーを重ねて最終画面を作る。
transformやopacityの変化は、レイアウトもペイントもやり直さず合成だけで済むことが多く、だからアニメーションはこの2プロパティが速い
アニメーション『ブラウザの描画パイプライン』を開く
図のように、DOM→CSSOM→レイアウト→ペイント→合成の順にハイライトが流れます。そして、これら各段とJSは同じ1本のメインスレッドで回るため、JSが重いとパイプライン全体が止まります。
この一連を「最初の意味あるピクセルを出すまでに、どれだけ最短で通せるか」で捉えたのがクリティカルレンダリングパス(※1)です。HTMLとレンダーブロッキングCSSと同期JSが最初の描画までのボトルネックで、ここを削る(CSSを小さく・JSを遅延)と初期表示が速くなります。
登場人物メモ:
- ※1 クリティカルレンダリングパス — URL取得から最初のピクセル描画までに、必ず通らねばならない資源と処理の連なり
なお、そのDOMを誰がどこで組み立てるか(サーバかブラウザか)は初期表示コストを大きく変えます。ブラウザ側でJSがDOMを組む方式(CSR)は、下の図でいう右側に寄るほどメインスレッドの初期負荷が増えます。
アニメーション『HTMLをどこで組み立てるか』を開く
やさしく言うと(初級)
- アドレスバーにURLを入れる(宛先を伝える)
- サーバから HTML を受け取る
- CSS で装飾を当て、見た目を整える
- JS を動かして、操作できるようにする
- 出来上がった画面を描画(※4 レンダリング)して、あなたに見せる
登場人物メモ:
- ※4 レンダリング — 設計図を、実際のピクセル(見える画面)に変換すること
ブラウザのセキュリティ境界
- 同一オリジンポリシー(SOP) — 別オリジンのデータに勝手に触れないよう制限する基本ルール
- CORS — 正当に跨ぐときの、サーバ側の許可の仕組み
- CSP(Content-Security-Policy) — SOP/CORSと並ぶ境界。読み込んでよいスクリプトの出所を制限し、不正なスクリプト実行を防ぐ
- 保存領域 — Cookie(サーバに自動送信)/localStorage(手元だけ)の使い分け
- 開発者ツール — 描画・通信・パフォーマンスを観察できる
この部分をもっと深く(上級)
中級では「別オリジンは既定で制限」と押さえました。上級では、その境界の定義と越え方の手順を精密にします。
- オリジンの定義 — スキーム・ホスト・ポートの3つ組が完全一致してはじめて同一オリジン。
https://a.comとhttp://a.com(スキーム違い)、a.comとapi.a.com(ホスト違い)はすべて別オリジン - 同一オリジンポリシー(SOP) — 別オリジンの応答中身をJSから読ませない基本ルール。画像や
<script>の読み込み自体は許すが、fetchで中身を読むのは別 - CORS — サーバが応答ヘッダ(
Access-Control-Allow-Originなど)で「このオリジンには中身を見せてよい」と明示的に許可する仕組み - プリフライト(※1) — 危険になりうる要求(独自ヘッダや
PUT・DELETEなど)では、本番の前にOPTIONSメソッドで予備問い合わせを送り、サーバの許可を先に確かめる。単純なGETなどは省略される - 資格情報つき — Cookieを乗せて跨ぐには、送る側の設定に加えサーバ側の
Access-Control-Allow-Credentialsが要り、Allow-Originに*は使えない(オリジンを名指しする)
この境界は攻撃対策と表裏一体です。緩めすぎたCORSは情報漏れの穴になり、SOPが崩れればXSSの被害も広がります。別オリジンのAPIを叩くときに出る「CORSエラー」は、この許可設定の不足そのものです。
登場人物メモ:
- ※1 プリフライト — 本番リクエストの前に
OPTIONSで「送ってよいか」を確かめる予備の往復
やさしく言うと(初級)
- タブ・履歴・ブックマーク — ページを切り替え、たどる
- Cookie(※5) — ログイン状態などを覚えておく小さなメモ
- 検索 — ブラウザ自身が探すのではなく、検索エンジンにお願いして結果を表示しているだけ
登場人物メモ:
- ※5 Cookie — サイトごとに保存される小さなデータ。「ログイン中」を覚えるのに使う
⚠️ うまくいかないとき
- リフロー多発で重い — レイアウトを何度も再計算させている(まとめて変更する)
- JSのブロッキング — 重いJSが描画を止める(分割・遅延読み込み)
- CORSエラー — サーバの許可設定が無く、別オリジンAPIが弾かれる
- CLS(表示中のガタつき) — 画像や広告の領域を先に確保していない
この部分をもっと深く(上級)
- ロングタスク — 1つのJSタスクが長く、その間コールスタックが空かず描画も入力も止まる。処理を分割し、隙間を返す
- 強制同期レイアウト(レイアウトスラッシング) — 幾何情報の読み取り(
offsetWidthなど)と書き込みを交互に繰り返し、レイアウトを何度も強制計算させる。読みをまとめてから書きに直す - 合成できないアニメーション —
widthやtopを毎フレーム変えるとレイアウト+ペイントが走り重い。transform/opacityなら合成だけで済む - マイクロタスクの暴走 — Promiseチェーンが自分自身を延々と積むと、マイクロタスクが尽きず描画の隙間が来ない(見かけ上フリーズ)
- メモリリークによるGC多発 — 外れない参照(消し忘れたイベントリスナ等)でオブジェクトが溜まり、GCが頻発してカクつく
ここまでの「1本のメインスレッドをどう空けるか」という視点は、URLを打ってから表示されるまでの④「組み立てる」を、性能の観点から裏返したものです。
やさしく言うと(初級)
- 真っ白 — JSのエラーで組み立てが止まった
- レイアウトが崩れる — CSSやJSが読み込めていない
- 古い表示のまま — 前に受け取ったもの(キャッシュ)が残っている
- 重い・カクつく — JSの処理が多すぎる
理解度チェック
そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。
問1. 別オリジンのAPIをJSから呼ぶと既定でブロックされ、サーバ側の許可設定が要る仕組みは?
問2. HTMLを解析してできる「要素の木構造」を何と呼ぶ?
問3. HTMLからDOMができるように、CSSを解析してできる木構造を何と呼ぶ?
問4. 「読み込んでよいスクリプトの出所を制限し、不正なスクリプト実行を防ぐ」ブラウザの境界はどれ?
問5. Cookieとlocalstorageの違いとして正しいのはどれ?
問6. 表示の途中で画像や広告が入り込み、レイアウトがガタッとずれる(領域を先に確保していない)現象を何という?
問7. JSの実行と画面の描画が奪い合う、ブラウザの主となる1本の実行の流れを何と呼ぶ?
問8. JSがDOMを書き換えたとき、各要素の位置や大きさを計算し直す再計算を何と呼ぶ?