やあ、こんにちは。Webの広大な海へようこそ。
フロントエンドという仕事をしていると、たまに「なぜか画面がカクつく」「スクロールが重い」という謎の現象にぶつかることがあるよね。
実はそれ、ブラウザが裏側で必死に「計算のやり直し」をさせられているせいかもしれないんだ。今回は、その犯人である「レイアウトスラッシング(Layout Thrashing)」という現象について、ブラウザの気持ちになりきって解説していくよ。
—
ブラウザの「宿題」と「お絵かき」のルール
まず、ブラウザがどうやって画面を表示しているか、例え話をしよう。
ブラウザは、君が書いたHTMLという「指示書」を元に、一生懸命お絵かきをする画家さんだと思ってほしい。
1. 解析(パース): HTMLを読み解いて、「どこに何があるか」の設計図を作る。
2. 計算(レイアウト): 「この要素の幅は? 位置はどこ?」を計算して、キャンバスの配置を決める。
3. 描画(ペイント): 実際に色を塗る。
ここで大事なルールがある。ブラウザは「まとめて効率よくやりたい」という性格なんだ。
「まずは設計図を全部読み込んで、次に配置を計算して、最後にまとめて色を塗るぞ!」というふうに、一度のフローで仕事を終わらせようとする。これが一番速いからね。
—
悪夢の「レイアウトスラッシング」とは?
ところが、僕ら開発者が意図せずブラウザを混乱させてしまうことがある。それが「レイアウトスラッシング」だ。
例えるなら、「宿題を提出しに行ったはずなのに、先生が『あ、やっぱりここ書き直して』と言い、書き直した直後に『あ、ここも直して』と何度も呼び戻される状況」だよ。
具体的には、JavaScriptでこんなことをすると発生する。
// 悪い例:DOMの読み書きを交互に行う
const box = document.getElementById(‘box’);
// 1. 書き込み(スタイルを変更)
box.style.width = ‘200px’;
// 2. 読み込み(ブラウザは「計算しなきゃ!」と強制される)
console.log(box.offsetWidth);
// 3. 書き込み(また変更!)
box.style.width = ‘300px’;
// 4. 読み込み(また計算させられる!)
console.log(box.offsetWidth);
なぜこれがダメなのか?
ブラウザは本来、JavaScriptの処理が終わった後にまとめて「レイアウト計算」をしたいんだ。でも、途中で `offsetWidth` のような「サイズを教えて!」という命令が来ると、「えっ、まだ途中だけど、君が今すぐ答えを知りたいなら、今の段階のレイアウトを強制的に計算するよ…!」と立ち止まってしまう。
これを「強制同期レイアウト(Forced Synchronous Layout)」と呼ぶんだ。これを何度も繰り返すと、ブラウザは計算と再計算で手一杯になり、画面がガクガクと震え出すわけだね。
—
回避するための「魔法の処方箋」
大丈夫、解決策はとてもシンプルだよ。「読み込み」と「書き込み」を分ければいいだけなんだ。
「先に全部書き込んで、その後にまとめて読み込む」という順番を徹底する。これだけで、ブラウザは無駄な計算をせずに済むようになる。
推奨される実装パターン(バッチ処理)
// 良い例:書き込みを先にまとめ、その後に読み込みを行う
const box = document.getElementById(‘box’);
// 【ステップ1】書き込みを先に全部終わらせる
box.style.width = ‘200px’;
box.style.height = ‘200px’;
// 【ステップ2】その後にまとめて読み込む(ブラウザは一度だけ計算すればOK!)
const width = box.offsetWidth;
const height = box.offsetHeight;
console.log(`サイズは ${width} x ${height} です`);
たったこれだけの工夫で、ブラウザの負担は劇的に減る。まるで、散らかった部屋を片付けるときに「先にゴミを全部まとめてから、次に掃除機をかける」のと同じくらい、スムーズな流れになるんだ。
—
最後に:完璧主義にならなくても大丈夫
「じゃあ、常にこのルールを完璧に守らないといけないの?」と思うかもしれないけれど、まずは「DOMの読み取りと書き込みが交互に並んでいないか?」と意識するだけで十分だよ。
Web開発の現場では、ライブラリ(ReactやVueなど)が裏側でうまく調整してくれることも多いけれど、こうしたブラウザの「中の人」の気持ちを知っているかどうかで、トラブルシューティングの質は圧倒的に変わる。
もし画面が重いなと感じたら、「ブラウザを何度も呼び戻していないかな?」と優しく問いかけてみてほしい。きっと、君の書いたコードはもっと軽快に、心地よく動いてくれるはずだよ。
応援しているよ。一緒にWebの世界を快適にしていこう!

コメント