Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第8章 View Source と DevTools はなぜ違うのか

この章では、View Source と DevTools が同じ HTML を別の形で見せているのではなく、最初から別の対象を見せているのだと整理します。ゴールは、ソースと DOM が食い違って見えたときに、「どちらが正しいか」と迷うのではなく、「どの段階の結果を見ているのか」を切り分けて説明できるようになることです。

前章では、HTML が壊れた入力に出会っても、閲覧を止めずに回復しながら読み進めることを見ました。この章では、その回復の前と後を、私たちがどこで観察しているのかを扱います。次の第3部では、こうした差を生む HTML 自体の設計思想へ進みます。

8.1 同じ文書でも観察している層が違う

View Source が見せるのは、ネットワークから受け取った元の HTML 文字列です。いわば、著者やサーバーがブラウザへ渡した入力そのものです。

一方で DevTools の Elements パネルが見せるのは、ブラウザがその入力をパースし、必要な補完や回復を行ったあとに扱っている DOM です。Elements パネルは、ブラウザがいま相手にしている要素の木を表示する画面だと思えば十分です。ここで見えているのは、文字列そのものではなく、ブラウザ内部で組み立てられた文書構造です。

この 2 つは、同じページに由来していても観察対象が違います。だから一致しないこと自体は異常ではありません。むしろ、第4章から第7章までで見てきた補完や暗黙終了や回復がある以上、違いが見えるほうが自然です。

8.2 tbodyp が差を目に見える形へ変える

もっとも分かりやすいのは、第5章と第6章で扱った例です。

<table>
  <tr><td>A</td></tr>
</table>
<p>前置き
<div>本文</div>

View Source では、この入力はほぼそのまま見えます。tbody は書かれておらず、p も閉じられていません。

しかし DevTools では違います。表には tbody が立ち上がり、div の手前で p が閉じられた形の DOM が見えます。ここで起きているのは、ブラウザが勝手に別の文書を作っていることではありません。元の入力を、表モデルや段落構造を保ったまま扱える形へ変換した結果が、DOM として現れているのです。

この差を知らないと、「ソースを書き換えられた」「DevTools が嘘を表示している」といった誤解が起きます。実際には、View Source は入力を、DevTools は解釈結果を見せています。両者の不一致は、ブラウザが不安定だからではなく、役割が違うから起きます。

8.3 View Source は著者の入力を調べる道具である

では、View Source はいつ使うのでしょうか。役割は明快です。著者が何を書いたのか、サーバーが何を返したのか、元の入力を確認したいときに使います。

たとえば、テンプレートエンジンがどんな HTML を出力したのか、レスポンスに含まれていた属性や要素は何か、整形前の改行やコメントがどう入っていたのか、といったことは View Source のほうが向いています。これは「ブラウザがどう理解したか」ではなく、「そもそも何が渡されたか」を見るための道具です。

ここで 1 つ区別しておきたいのは、View Source が見せるのは ERB や JSX のようなテンプレート記述そのものではない、ということです。見えているのは、それらが評価されたあとにサーバーやビルド結果から渡された HTML です。Rails アプリで調べものをするときも、app/views のテンプレートと View Source と DevTools は、それぞれ別の段階を見ています。

第7章で触れた validator との相性がよいのもこちらです。validator が検査するのは入力としての HTML なので、確認したい対象は回復前の文字列です。著者の入力に問題があるのかを詰めるなら、まず見るべきなのは View Source 側です。

8.4 DevTools はブラウザの現実を調べる道具である

一方で、CSS が効かない、JavaScript のセレクタが当たらない、思っていた場所に要素がない、といった実務上の問題を調べるときは DevTools が必要です。なぜなら、ブラウザが実際に描画し、スクリプトから参照しているのは DOM だからです。

たとえば table > tr が当たらない理由は、ソースに tbody がないからではなく、DOM では tr の親が tbody だからです。p の途中までを 1 つの段落だと思っていたのにスタイルの適用範囲がずれるのも、DOM 上では途中で暗黙終了しているからです。こうした問題は、入力を見ても最後までは分かりません。ブラウザが最終的にどんな構造を扱っているかを見ないと解けません。

さらに、現代のページでは JavaScript が DOM を書き換えることも珍しくありません。すると DevTools に見えているのは、パースと回復の結果だけでなく、スクリプト実行後の状態でもあります。View Source は最初に受け取った HTML を見せ続けますが、DevTools は「いまブラウザが相手にしている文書構造」を見せます。この違いを押さえると、「ソースにはない要素が見える」「属性値が違って見える」といった現象も整理しやすくなります。

ここで大切なのは、DevTools が「より正しい」わけではないことです。DevTools が見せているのは、ブラウザにとっての現実です。著者の入力を検証したいのか、ブラウザの現実を調べたいのかで、使う道具が変わります。

8.5 「どちらを見るべきか」は問いで決まる

実務で混乱しやすいのは、ソースと DOM を同じものだと思って調査を始めることです。そうすると、「ソースにはあるのに見つからない」「ソースにはないのに DOM にはある」という現象に毎回ひっかかります。

判断基準は単純です。何が送られてきたのか を知りたいなら View Source、ブラウザはいま何を相手にしているのか を知りたいなら DevTools を見る。この切り分けができると、第2部で見てきた多くの現象が、単なるブラウザの癖ではなく、観察層の違いとして整理できます。

ここまでで、HTML ではソースと完成形が一致しないことが珍しくないと分かりました。次の第3部では、その差がどんな設計思想から生まれているのかを、空要素やコメントや属性の省略といった個別の論点から見ていきます。

参考資料