コンソールはあなたに嘘をついている

ブラウザのDevToolsは、デバッグ中にあなたを誤解させることがあります。ツールが壊れているわけではありません。完璧な正確さよりも、スピードに最適化されているのです。

なぜ console.log を常に信頼できないのか、その理由を説明します。

• 遅延評価 (Lazy Evaluation) オブジェクトをログに出力するとき、ブラウザは即座にそのコピーを作成するわけではありません。ライブ参照(live reference)を保持します。ブラウザがプロパティを読み取るのは、矢印をクリックして展開したときだけです。クリックする前にコードがそのオブジェクトを変更した場合、表示されるのは古い値ではなく、新しい値になります。

• ハイゼンバグ効果 (The Heisenbug Effect) console.log を追加することで、逆にバグが隠れてしまうことがあります。ログの出力には時間とリソースが必要です。高速なコードにおいて、このわずかな遅延がアプリケーションのタイミングを変化させることがあります。これにより、観察している間だけレースコンディション(競合状態)が発生しなくなり、バグが消えてしまうことがあるのです。

• Reactステートの罠 setCount を呼び出した直後にステートをログに出力しても、古い値が表示されます。これはクロージャや、Reactの更新スケジューリングの仕組みによるものです。ログに出力される値は、次のレンダリングではなく、現在のレンダリングに属するものだからです。

• ソースマップのエラー 本番環境では、コードは難読化(minified)およびバンドルされています。ソースマップが古い、あるいは不正確な場合、コンソールは誤った行を指し示します。エラー自体は実在しますが、発生場所が間違っているのです。

より良いデバッグ方法:

  • structuredClone を使用してスナップショットを取得する オブジェクトを「今この瞬間」の状態のまま確認したい場合は、次を使用します: const snap = structuredClone(obj) console.log(snap)

  • 大きなオブジェクトの代わりにプリミティブ値をログに出す ID、タイムスタンプ、またはステータス文字列をログに出力します。これにより、遅延評価のリスクやパフォーマンスへの影響を軽減できます。

  • デバッガーを使用する ブレークポイントを使用して実行を一時停止します。これにより、コードのタイミングを変えることなく、実際のステートやコールスタックを検査できます。

  • フレームワークのDevToolsを使用する ReactやVueを使用している場合は、それぞれの専用DevToolsを使用してください。ログよりも正確にライフサイクルやレンダリングフェーズを表示してくれます。

コンソールは、素早い調査には非常に優れたツールです。しかし、それを最終的な「真実のソース(source of truth)」として扱わないようにしましょう。

Source: https://dev.to/gkoos/your-console-is-lying-to-you-3dlc