ブラウザの「メインスレッド」を制する者が、Webパフォーマンスを制する。
やあ。今日は少し腰を据えて、Chrome DevToolsの「Performance」タブの話をしよう。
多くのエンジニアが「なんとなく重いから」といって適当にリファクタリングをしては、結果が変わらず首を傾げている。だが、ブラウザのレンダリングパイプラインを理解し、Performanceタブを読めるようになれば、それはもう「運任せの最適化」ではなく「外科手術」に変わるんだ。
ブラウザのレンダリングは、まさに一つの巨大な工場だ。HTMLという設計図を受け取り、DOMとCSSOMという部品を組み合わせ、計算し、色を塗り、最終的にピクセルを画面に出力する。この全工程を支配しているのが「メインスレッド」という名の、たった一人の職人だ。
1. メインスレッドの「4つの大罪」を見抜く
Performanceタブでまず見るべきは、上段の「Main」スレッドのタイムラインだ。ここで特に注目すべきは、以下の4つの処理だ。
1. Recalculate Style (スタイル計算): CSSセレクタをマッチングし、各DOMノードに適用されるスタイルを決定する。ここで時間がかかっているなら、セレクタが複雑すぎるか、DOMが巨大すぎる。
2. Layout (レイアウト/リフロー): 要素の幾何学的な位置やサイズを計算する。これが走ると非常に重い。
3. Update Layer Tree (レイヤー生成): `z-index`や`transform`などで構成される合成レイヤーを再計算する。
4. Paint (ペイント): 色、文字、画像など、個々のピクセルを描画する。
「なぜかスクロールがカクつく」「ボタンを押した後の反応が遅い」。そう感じたら、すぐにPerformanceタブで録画(Record)ボタンを押し、対象のアクションを実行してほしい。「Long Task(赤い三角の警告)」が出ていれば、その職人(メインスレッド)がオーバーワークで倒れている証拠だ。
2. 「強制同期レイアウト」という罠
現場で最もよく見るパフォーマンス低下の主犯は、JavaScriptによる「強制同期レイアウト」だ。これは、ブラウザがLayoutを完了させる前に、JSからLayout情報(`offsetWidth`や`getBoundingClientRect`など)を無理やり要求する行為を指す。
これが発生すると、ブラウザは「ああ!計算中なのに値が必要なのか!じゃあ今すぐ計算を終わらせなきゃ!」と、本来なら後回しにできる計算を強制的に割り込ませる。
悪い例:強制同期レイアウトの温床
// ループ内で読み書きを繰り返すと、ブラウザは毎回Layoutを強制される
const boxes = document.querySelectorAll(‘.box’);
boxes.forEach((box) => {
// 1. スタイル変更
box.style.width = ‘100px’;
// 2. 直後にLayout情報を要求(ここで強制同期レイアウトが発生!)
const width = box.offsetWidth;
// 3. 次の処理に影響を与える
box.style.height = `${width}px`;
});
これを防ぐには「読み込みと書き込みを分離する(Batching)」のが鉄則だ。
良い例:FastDOM的なアプローチ
// 読み込み(Layout情報取得)はまとめて行う
const widths = Array.from(document.querySelectorAll(‘.box’)).map(box => box.offsetWidth);
// 書き込み(スタイル変更)もまとめて行う
// こうすることで、ブラウザのLayoutエンジンは一度の計算で済ませられる
document.querySelectorAll(‘.box’).forEach((box, i) => {
box.style.width = ‘100px’;
box.style.height = `${widths[i]}px`;
});
3. レンダリング解析の極意:プロの眼差し
Performanceタブを分析する際、ただ「長いバー」を見つけるだけでは足りない。バーをクリックした後に表示される「Summary」タブと「Bottom-Up」タブを見ろ。
- Summary: そのタスクが何に時間を費やしたか(ScriptingなのかRenderingなのか)の比率が見える。
- Bottom-Up: どの関数が重いかの犯人特定に役立つ。`Recalculate Style`の時間が長いなら、CSSセレクタの深さを疑え。`Layout`が長いなら、DOMのネストが深すぎないかを確認しろ。
現場の泥臭い話だが、「CSSのプロパティひとつで、Layoutをスキップできる」ということを忘れるな。`top`や`left`を変えるとLayoutが走るが、`transform`や`opacity`ならComposite(合成)だけで済むことが多い。
まとめ:ブラウザと会話しろ
ブラウザは優秀な機械だが、エンジニアが書いたコードの「意図」までは汲み取ってくれない。だが、Performanceタブという対話ツールを使えば、ブラウザがどこで苦しんでいるのか、なぜ溜息をついているのかが手に取るようにわかるはずだ。
明日からコードを書くときは、自分の書いた一行が「メインスレッドにどれだけの負荷をかけるか」を想像してみてくれ。その積み重ねが、一流のフロントエンドエンジニアへの最短ルートだ。
何かわからないことがあれば、またいつでも聞きに来い。現場で揉まれることは、最高の学習だ。健闘を祈る。

コメント