「パフォーマンスで選ぶ」JS vs CSS|ブラウザの負荷を見える化する判断基準

「パフォーマンスで選ぶ」JS vs CSS|ブラウザの負荷を見える化する判断基準
C
クリオ
Web制作ディレクター / フロントエンジニア

こんにちは!

今日は「ブラウザの負荷を見える化する」というテーマで、JavaScript と CSS の選び分け方についてお話しします。

「動けばいい」が落とし穴だった話

僕も昔、ほんま恥ずかしい失敗をしたんですが、「とりあえず動く」ことを優先して、めっちゃ重い実装をしてしまったことがあります。
当時は勤務先の案件で、ボタンをホバーしたときに複数の要素がふわっと現れるエフェクトが必要だったんですね。
僕はすぐに JavaScript で setInterval() を使って値を変更する処理を書いてしまいました。

もう最悪です。
スマートフォンで見たら、アニメーション中にページがカクカクになるわ、バッテリーめっちゃ減るわで、クライアントからクレームが来たほどですよ。

後から先輩に指摘されて気づいたんですが、その処理は CSS の animationtransition で十分対応できるものでした。
結局 CSS に書き換えて、パフォーマンスは劇的に改善しました。

その時から僕は学びました。
「動く」だけじゃなくて、「どれだけ効率的に動くか」がめっちゃ大事やということをです。

ブラウザの処理フローを理解する

ここからは技術的な話になるんですけど、ブラウザがどうやって画面を描画するか、簡単に説明します。
この仕組みを理解すると、JS か CSS かの判断がぐっと楽になりますよ。

ブラウザの描画パイプラインは、ざっくりこんな流れです:

  1. JavaScript 実行 → JavaScript コードが走る
  2. スタイル計算 → CSS がどう適用されるか計算される
  3. レイアウト → 各要素の位置やサイズが決まる
  4. ペイント → 色や背景などが描画される
  5. コンポジット → レイヤーが合成されて画面に表示される

ここで重要なのが、JavaScript で DOM を触ると、このフローの1番目からやり直すということです。
つまり、毎回めっちゃ重い処理をしているわけですよ。

一方、CSS だけで実装すれば、GPU が効率的に処理してくれるプロパティが多いんです。
例えば transformopacity は「コンポジット」のステップだけで済むので、レイアウト再計算が発生しません。

現場で見るのが、JavaScript でしょっちゅう要素の lefttop を変更している人なんですが、あれはほんまにやめた方がいいですよ。
毎回レイアウト再計算が走ってしまいます。

実践的な選び分けの3つのポイント

では実際に、どういう判断基準で JS か CSS か決めるのか、3つのポイントを紹介します。

1. 「60fps」でも滑らかか、デバイス依存か

スマートフォンやタブレットなど、低スペックデバイスで実装を試してみてください。
もし JavaScript で毎フレーム処理をしていて、低スペックデバイスではカクつく場合は、CSS に切り替えることを強くお勧めします。

CSS のアニメーションは GPU 加速の恩恵を受けやすいので、デバイス依存が小さいんです。
僕が最初に失敗した例も、これが原因でした。

2. 「ユーザーインタラクション」に即座に反応する必要があるか

ボタンをクリックしたときに、素早く何かが起こる必要がある場合、CSS の :active:hover 疑似クラスが活躍します。
これらは JavaScript より遅延が少ないんです。

逆に「ユーザーのマウス位置を追いかけて何かが動く」みたいなケースは、JavaScript で mousemove イベントを監視するしかありません。
こういう場合は、最初から JavaScript で実装するのが自然です。

3. 「複数の条件」を組み合わせるか、シンプルか

例えば「ボタンをホバーしたら色が変わって、同時にアイコンが回転する」みたいなシンプルな挙動は、CSS で十分です。
むしろ CSS でいけるなら CSS にしましょう。

ただ「スクロール位置によって色が変わったり、ウィンドウサイズでアニメーションの速度が変わったり…」みたいに複雑な条件が絡むなら、JavaScript で実装した方が保守しやすいです。

現場で良く見るのが、CSS だけで頑張ろうとしてめっちゃ複雑な @keyframes を書いている人なんですが、その場合は JavaScript で状態管理した方がコードが読みやすくなることが多いですよ。

まとめ

「JS か CSS か」って判断は、実は「ブラウザの負荷がどこにかかるか」を理解できれば、自然と答えが見えてくるんです。

僕からのアドバイスとしては:

  • シンプルなアニメーション、ホバーエフェクト → CSS で実装
  • 60fps を維持したい、デバイス依存を避けたい → CSS の transformopacity を活用
  • 複雑な状態管理、リアルタイムなユーザーインタラクション → JavaScript で実装
  • 迷ったら、まずは CSS で実装してみて、うまくいかなかったら JavaScript に変更

最初は「どっちでやったらいいんだろう…」と迷うかもしれませんが、実装を重ねていると感覚がつかめてきますよ。
大事なのは、「とりあえず動く」で満足しないということですね。

僕のあの失敗から、ほんま勉強になりました。
皆さんも、パフォーマンスを意識した実装を心がけてくださいね。

Web制作で困ったことがあったら、またこのブログを覗いてくださいね!

― クリオ