こんにちは!Webブラウザの仕組みの旅へようこそ。
フロントエンドのアーキテクトとして日々いろんなコードと格闘していますが、今回は「ブラウザが画面を表示するまでの一番最初の関所」、HTMLパーサーのトークン化プロセスについてお話ししますね。
「HTMLの解析? DOMツリー? なんだか難しそう……」って身構えちゃいましたか?
大丈夫ですよ、安心してください。今日はお買い物のレシートや、言葉を単語に分解するパズルみたいな身近な例えを交えながら、とっても優しく紐解いていきます。
ブラウザの頭の中を覗く冒険、一緒に楽しんでいきましょう!
—
そもそも、ブラウザはHTMLをどう見ているの?
私たちが普段テキストエディタで書いているHTMLファイル(`index.html`など)は、人間から見れば「ただの文字の羅列」ですよね。
こんにちは!
でも、冷徹な(そして超高速な)Webブラウザにとって、このコードはただの「1文字ずつの長い文字列(ただの文字の塊)」でしかありません。
ブラウザは、この文字の塊をそのままでは理解できないんです。「お、ここに `
` があるから大見出しだな」と理解するためには、文字を意味のある最小単位に「ばらして整理」してあげる必要があります。
この、「ただの長い文字列を、意味のあるパーツ(トークン)に分解していく作業」こそが、今回主役にする「トークン化(字句解析)」と呼ばれるプロセスなんです。
—
例え話:レジの「バーコード読み取り」と「品目シール」
このトークン化のプロセス、何かに似ていると思いませんか?
そう、スーパーのお買い物のレジの仕組みにすごくよく似ています。
お買い物カゴに入っているのは、形も大きさもバラバラの商品(HTMLの文字列)です。
レジの店員さん(HTMLパーサー)は、商品を一つひとつバーコードリーダーでピッ!と読み取っていきます。
- 「あ、これは『牛乳』っていう商品タグだな」
- 「こっちは『パン』っていう商品タグだな」
- 「これはカゴの中の商品の名前じゃなくて、ただの『お惣菜のパッケージの文字』だな」
バーコードをピッ!と読み取るたびに、レジの画面には「商品名:牛乳、価格:200円」という意味のある単位でデータが登録されていきますよね。
ブラウザのトークン化もこれと全く同じです。
ブラウザはHTMLという長い文字列のトンネルを左から右へ1文字ずつ(あるいは数文字ずつ)進みながら、「あ、ここはタグの始まりだ!」「ここは中身のテキストだな!」と切り分けて、ペタペタと「意味のシール(トークン)」を貼っていくのです。
—
トークン化の舞台裏:ステートマシン(状態の切り替え)ってなに?
さて、ここから少しだけ裏側の仕組みをのぞいてみましょう。
ブラウザは、文字を切り分けるために「ステートマシン(状態機械)」という仕組みを使っています。
難しそうに聞こえますが、要するに「今のモードは何か?」を常に切り替えているだけです。例えば、以下のようなモード(状態)を行ったり来たりしています。
1. データ状態(Data State): 普通のテキストを読んでいるモード
2. タグオープン状態(Tag Open State): 「`<`」を見つけて、「おっ、何かタグが始まるぞ!」と身構えるモード
3. タグ名状態(Tag Name State): 「`h1`」や「`p`」といったタグの名前を読んで、「あ、見出しタグだな」と確定させるモード
4. 属性名状態(Attribute Name State): `class=”box”` の `class` の部分を読んでいるモード
ブラウザは、HTMLの文字列を左から右へ1文字ずつスキャンしながら、今自分がどのモードにいるべきかをものすごいスピードで切り替えています。
トークンの5つの代表的な顔ぶれ
こうして文字を切り分けた結果、ブラウザは以下のような「トークン(部品)」のリストを作ります。
- StartTag(開始タグ)トークン: `
` や `
` など- EndTag(終了タグ)トークン: `
` や `
` など
- EndTag(終了タグ)トークン: `
- Character(文字)トークン: タグに挟まれた実際のテキスト(「こんにちは!」など)
- Comment(コメント)トークン: `` の部分
- EOF(End Of File)トークン: 「もうファイルの最後まで読み終わったよ!」という合図
ブラウザはこのトークンの束を次々に作り出し、次のステップである「DOMツリーの構築」へとバトンタッチしていくのです。
—
実践:ブラウザの気分になってHTMLを分解してみよう
百聞は一見にしかず。私たちが普段書いている簡単なHTMLコードを、ブラウザがどのようにトークンに分解しているのか、実際に目で見てみましょう。
以下のサンプルコードを見てください。
ハロー、ワールド!
このコードをブラウザの「トークン化プロセス」に通すと、内部的には次のようなトークンの流れ(イメージ)に変換されます。
1. StartTag トークン
- タグ名: `div`
- 属性: `class=”greeting”`
2. Character トークン
- 文字列: `\n ` (改行やインデントのスペース)
3. StartTag トークン
- タグ名: `p`
4. Character トークン
- 文字列: `ハロー、ワールド!`
5. EndTag トークン
- タグ名: `p`
6. Character トークン
- 文字列: `\n`
7. EndTag トークン
- タグ名: `div`
8. EOF トークン (おしまい!)
「おや、タグとタグの間の改行やスペースも、ちゃんと『Characterトークン』として読み込まれているんだな」って気づきましたか?
そうなんです!ブラウザは私たちが書いたコードの空白や改行すらも、サボらずにちゃんとトークンとして受け取っているんです。これが後のDOMツリーに影響を与えることもあるので、地味だけどとても重要なポイントですよ。
—
つまずきポイント:HTMLが多少崩れていても動く理由
Web制作を始めたばかりの頃、「あれ、閉じタグの `

コメント