こんにちは!フロントエンドの現場を渡り歩いているチーフアーキテクトの私です。
Webサイトを作っているとき、「JavaScriptでちょっとDOMをいじっただけなのに、なんだか画面がカクつく……」なんて現象に頭を悩ませたことはありませんか? 「コードは綺麗に書いたはずなのに、なぜ?」と、モニターの前で途方に暮れてしまう気持ち、痛いほどよく分かります。私も昔は何度もその壁にぶつかりました。
実はそのカクつき、犯人は「スタイル再計算(Style Recalc)」という、ブラウザの裏側のちょっとしたおせっかい(非効率な頑張り)にあることが多いんです。
今回は、このスタイル再計算の裏側を、難しい専門用語をできるだけ排除して、身近な例えを交えながら優しく解きほぐしていきましょう。大丈夫、仕組みさえ分かってしまえば怖くありませんよ!
—
1. ブラウザの中では何が起きている?「スタイル再計算」の正体
私たちが普段何気なく書いているHTMLとCSS。ブラウザはこれらをそのまま画面に表示しているわけではありません。
HTMLをパース(解析)して「DOMツリー」という家族の家系図のような構造を作り、CSSをパースして「CSSOMツリー」というルールブックを作ります。そして、この2つをガチャンと合体させて、「よし、この要素は赤色で、大きさはこのくらいだな!」と計算するプロセスが発生します。これがスタイル計算です。
問題は、JavaScriptなどでDOMを書き換えたとき(例えば、ボタンを押したらリストの項目が1つ増えた、など)です。
ブラウザは、「おいおい、DOMが変わったぞ! 全部のルールブックをもう一回見直して、誰にどのスタイルが適用されるか再確認しなきゃ!」と、慌ててスタイル再計算を始めます。
お買い物のレジに例えてみよう
これを、スーパーマーケットのレジに例えてみましょう。
あなたがお買い物カゴ(DOM)に新しい商品を1つポンと追加したとします。
真面目な店員さん(ブラウザ)は、カゴの中身が変わった瞬間、お店にある全商品の値札と割引ルール(CSSセレクタ)の冊子を最初から最後までパラパラとめくり直し、カゴの中身と照らし合わせるという作業を始めました。
……ちょっと待って! たった1つ商品を追加しただけなのに、お店全体のルールを最初から総チェックするのは、どう考えても非効率ですよね?
これが、スタイル再計算が重くなってしまうメカニズムの正体です。
—
2. なぜCSSセレクタの書き方でブラウザの苦労が変わるのか?
ブラウザがルールブックをめくるとき、実は「読み方のコツ」があります。ここが今日のハイライトです!
皆さんはCSSを書くとき、どちらの書き方を好みますか?
/ パターンA:親切な目印がある /
.card-title {
color: #333;
}
/ パターンB:大所帯を右から探す /
.user-profile .card .card-body h2 {
color: #333;
}
実はブラウザは、CSSセレクタを「右から左へ」読み込みます。
パターンBの場合、ブラウザはまず「このページにある全ての `h2` タグを探そう!」と血眼になり、見つかったら「その親に `.card-body` はあるか?」「さらにその上に `.card` はあるか?」と、わざわざ遡って確認作業をします。
これは、広い遊園地で迷子を探すときに、「『佐藤さん』という名前の人を全員集めて、その中で今日赤い服を着ていて、さらに昨日も来た人を探す」ようなもの。そりゃあブラウザも疲れてしまいます。
つまずきポイント:深すぎる階層と「」の多用
「子孫セレクタ(スペースで繋ぐ書き方)」を何階層も重ねたり、すべてを対象にする全称セレクタ(“)を多用したりすると、ブラウザの照合作業は爆発的に重くなります。これが、DOM変更時のカクつき(Jank)を引き起こす原因になるのです。
—
3. スタイル再計算を軽くする!今日から使える設計のコツ
では、ブラウザに無駄な苦労をさせず、いつもサクサク動く優しいWebサイトを作るにはどうすればいいのでしょうか? 実践的な3つの指針をご紹介します。
指針①:セレクタはなるべく「浅く、フラットに」書く
先ほどのパターンBのような長すぎるセレクタは避けましょう。BEMなどのCSS設計手法を取り入れて、クラス名を `.user-profile__title` のように一意のシンプルな名前にするのが理想です。これならブラウザは一発でターゲットを見つけられます。
指針②:CSSカスタムプロパティ(変数)を上手に使う
色や余白の変更をJavaScriptから行う場合、要素のクラスをごっそり変えるよりも、ルート(`:root`)のCSS変数を書き換えるアプローチをとると、スタイル再計算の範囲を最小限に抑えられることがあります。
指針③:アニメーションは `transform` と `opacity` に絞る
スタイル再計算だけでなく、その後の「レイアウト(位置の計算)」や「ペイント(描画)」まで巻き込んでしまうプロパティ(`width` や `top` など)があります。
動かしたいときは、ブラウザがハードウェアアクセラレーション(GPUの力)を使ってひょいと動かせる `transform` や `opacity` を使うのが、現場のプロとしての定石です。
—
4. 実践:ブラウザに優しいコードの書き方
それでは、実際にエディタに貼り付けて試せるシンプルなサンプルを見てみましょう。CSSセレクタの「軽さ」を意識した書き方の一例です。
ブラウザに優しいカードタイトル
余計なセレクタの深さがないため、DOMが動いてもサクサク再計算されます。
—
おわりに:ブラウザと仲良くなろう
Webブラウザは、私たちが書いたコードを忠実に、そして一所懸命に画面に描き出そうとしてくれる、いわば「優秀だけど真面目すぎる相棒」です。
私たちがCSSのセレクタを少しシンプルにしたり、DOMの変更を最小限に抑えたりしてあげるだけで、ブラウザは「ふぅ、助かったよ!」と軽快な動作で応えてくれます。
最初から完璧にやろうとしなくて大丈夫です。まずは「あ、セレクタは右から読まれるんだっけ」「あんまり深くネスト(階層化)させないようにしよう」という意識を持つこと。それだけで、あなたの書くコードは確実にブラウザに愛される、パフォーマンスの高いものに変わっていきますよ。
それでは、快適なフロントエンドライフを!

コメント