再現性のないバグの犯人を特定する方法|デバッグの裏技と心構え
こんにちは!
今日は「再現性のないバグの犯人を特定する方法」について解説します。
これ、ほんまにめっちゃ困るやつですよね。
「自分の環境では大丈夫なんですけど…」「時々崩れるんですけど原因がわかりません…」
こういった再現性のないCSSバグって、現場で最も厄介な問題の一つなんです。
この記事の内容
再現性のないバグが生まれる理由
僕も昔、営業さんから「ユーザーの報告では崩れてるんです」と言われて、自分のPCで何度確認してもどうしても再現できなくて、めっちゃ焦ったことあります。
その時にわかったのは「再現性がない = 条件が限定的」っていう大事な法則なんです。
再現性のないバグって、実は原因は確実に存在してるんですよ。
ただ、その条件が:
- 特定のブラウザでだけ発生する
- 特定の画面サイズでだけ発生する
- キャッシュが溜まった状態でだけ発生する
- 特定のOSやデバイスでだけ発生する
- JavaScriptが特定の順番で実行された時だけ発生する
こういった限定的な条件なので、見つけにくいわけです。
だからこそ、僕たちは「体系的に条件を絞っていく」というアプローチが必要になります。
環境差分を疑う:ブラウザとキャッシュの落とし穴
再現性のないバグに直面したら、まず真っ先にやるべきことが「環境を変える」です。
これはめっちゃ重要なので、チェックリストを作っておきました。
ブラウザの切り替え
Chrome、Safari、Firefox、Edgeで順番に開いてみてください。
意外かもしれませんが、ブラウザによってCSSの解釈が微妙に違うことがあります。
特に line-height や letter-spacing、transform の挙動は要注意です。
キャッシュのクリア
これ、現場で何度も経験してます。
古いCSSがブラウザに残ってて、新しいファイルが読み込まれてないパターンですね。
デベロッパーツールで「Network」タブを開いて、ステータスコードを確認するといいですよ。
もし 304 Not Modified が出てたら、キャッシュが効いてる状態です。
確実にクリアするには:
- DevTools で右クリック → 「キャッシュを空にしてハード再読込」を選択
- または
Ctrl + Shift + Delete(Windows)/Cmd + Shift + Delete(Mac)でブラウザキャッシュを直接削除
デバイスの切り替え
スマートフォン、タブレット、デスクトップで別々に確認してください。
レスポンシブ対応のサイトの場合、スマホエミュレーターではなく「実機で」試すのがほんま大事です。
エミュレーターと実機の挙動が違うことも珍しくありませんから。
スクリーンサイズとメディアクエリを徹底検証する
再現性のないバグで次に疑うべきは「ブレイクポイント周辺」です。
よくあるケースが、メディアクエリの境界線で予期しない動作が発生するパターン。
たとえば、max-width: 768px と min-width: 769px が重複してたりすると、まさにその境界値で動作が変わります。
実際の確認方法としては:
- DevTools を開いて「デバイスモード」に切り替える
- ウィンドウ幅を1px ずつ変更しながら確認する
- メディアクエリが動作しているか「Styles」パネルで確認する
「Styles」パネルのメディアクエリのセクションをチェックすると、「このルールはメディアクエリで適用された」「こっちは適用されていない」がひと目でわかります。
僕の経験では、こういった「メディアクエリの干渉」が原因の再現性なしバグって、意外に多いんですよ。
CSSの継承と詳細度の「見えない競争」を追跡する
ここからが上級編ですね。
再現性のないバグの犯人が「親要素のスタイル」だったり「詳細度の競争」だったりするケースです。
詳細度の競争を見える化する
DevTools の「Styles」パネルを見ると、適用されているCSSと打ち消されているCSSが表示されます。
打ち消されているルール(打ち消し線が引かれてる)を見て、「あ、こっちが勝ってるのか」と判断できるわけです。
たとえば:
.container .button { color: blue; }(詳細度: 0, 2, 1).button { color: red; }(詳細度: 0, 1, 0)
この場合、前者の方が詳細度が高いので青色が勝ちます。
でも、「赤色で表示されてるんだけど…」という状況が起きると、「あ、parent から何か継承されてるのかな」と考えるわけです。
計算済みスタイルを確認する
DevTools の「Computed」タブを開くと、実際に要素に適用されている全スタイルが表示されます。
ここで確認すると「あ、このプロパティはこのファイルのこの行で定義されてるんだ」と、原因を特定できます。
特に z-index や margin、padding の競争は、「見た目では同じに見えても実は別の値が適用されてる」みたいなことが起こるんで、ここで確認するのが必須です。
親要素の影響を切り分ける
再現性のないバグの中には「特定の親要素が存在した時だけバグる」というパターンもあります。
その場合は:
- 該当要素を DevTools で右クリック → 「Inspect」
- 親要素を一つずつ選んで「このクラスが原因かな」と仮説を立てる
<style>タグで一時的に親要素のスタイルをdisplay: noneにしてみる
そうするとバグが消えるかどうかで、親要素が原因かどうかわかります。
まとめ