0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

冬が来て毎日起きるのが辛いです。
面接ラッシュな中DOMを勉強し続けます。
HTMLがDOMになるまでの過程を勉強します。

HTMLがDOMになるまでの流れ

HTMLファイルは単なる「テキスト」。
ブラウザはこのテキストを解析 => DOMツリーを構築する。

各段階で、違う処理がされる
HTMLバイト列 =①=> 文字列 =②=> トークン =③=> ノード =③=> DOMツリー

イメージのつきやすい画像⬇️
https://web.dev/articles/critical-rendering-path/constructing-the-object-model?hl=en

①HTMLバイト列から文字列

ネットワークから受け取るHTMLは、「テキスト = バイト列」。
まずこれを文字列に変換する。
文字列 = 文字が連続して並んだもの
バイト列 = 意味や形式に囚われず0から255までの数値データ(バイト)が連続して並んだもの

⬇️ブラウザがHTMLファイルの文字エンコーディング(バイトの並びがどのように解釈されるかを定める)を決定するときの優先順位
1位. HTTPヘッダのContent-Type
2位. BOM(Byte Order Mark)
3位. <meta charset="...">
4位. <meta http-equiv="Content-Type" content="..."> (古いやつ)
5位. 自動判定
6位. デフォルト(UTF-8)

バイト列:    3C   70   3E   E3 82 84   E3 81 BB   3C   2F   70   3E
=>文字列:     <    p    >    や         ほ         <    /    p    >

②文字列からトークン(トークン化)

文字列 = 文字が連続して並んだもの
トークン = 特定の価値や権利、情報を代替するデータや記号 = 意味を持つ最小単位のもの

ってことは、トークン化 = 文字に意味を持たせる

文字列
<div class="container">Hello</div>
トークン化
<div class="container">Hello</div>
 ├─ "<" を見た → 「タグだ!」
 ├─ "div" を見た → 「タグ名は divだ!」
 ├─ "class=..." を見た → 「属性があるゾ!」
 ├─ ">" を見た → 「タグ終わり!」→ StartTagトークン発行
 ├─ "Hello" を見た → Characterトークン発行
 ├─ "</div>" を見た → EndTagトークン発行
トークン
- DOCTYPE(もしあれば)
- StartTag: div
(Attribute: class="container")
- Character: Hello
- EndTag: div
- EOF

トークン化を行うのは何者?
=> トークナイザ = 状態マシン(state machine)
文字を1つずつ読みながら状態を遷移させていく。

状態ってなんやねん
=> 以下のようなものたち
・Data state:通常のテキストを読んでいる("Hello" を見てる)
・Tag open state:<を読んだ直後(「タグだ!」)
・Tag name state:タグ名を読んでいる(「タグ名は divだ!」)
・Attribute name state:属性名を読んでいる
・Attribute value state:属性値を読んでいる

メモ⬇️ :状態マシンの説明(わかりやすい)
https://qiita.com/saltheads/items/8331e14f4d3b37f511aa

メモ⬇️ :トークン化詳しく(死ぬほど読みづらいbut詳しい)
https://triple-underscore.github.io/HTML-parsing-ja.html#data-state

③トークンからノード(同時にDOMツリー)

トークン = 意味を持つ最小単位(StartTag, EndTag, Characterなど)
ノード = DOMツリーを構成する1つ1つの部品

トークン = 解析結果
ノード = 実際のオブジェクト

トークン                      ノード
─────────────────────────────────────────
StartTag: div        =>      Element: <div>
Character: Hello     =>      Text: "Hello"
EndTag: div          =>      (新しいノードは作らない)

EndTagの役割は?
EndTagは「このノードの中身はここで終わり」という合図。
「今見ているノード = 現在地」を親に戻す。

トークンを順番に処理する
1. StartTag: div   → Elementノード作成(📍現在地)
2. Character: Hello → 現在地(div)の「子」としてTextノード追加
3. EndTag: div     → 現在地を親に戻す(divの中身終わり)

補足:scriptタグとパース

<script>タグはJavaScriptを読み込むためのタグ。

<script src="app.js"></script>

ブラウザはこのタグに出会うと「パース = HTML → DOMツリーの処理」を止めてJavaScriptのダウンロードと実行を待つ。

scriptタグがあるとき〜
<p>Hello</p>
<script src="app.js"></script>   <= ここで止まる
<p>World</p>                     <= app.jsが終わるまでDOMに追加されない

deferasync = パースが止まるのを避ける。

どうやって?
deferとasyncは両方パースと外部ファイルのダウンロードが同時進行で行われる。
2つの違いは?
defer = パースが全部終わってから実行
async = ダウンロード終わった瞬間に実行(パースの途中でも割り込む)

メモ⬇️:わかりやすい図とわかりやすい説明
https://qiita.com/phanect/items/82c85ea4b8f9c373d684

まとめ

「状態マシン」めっちゃ面白い
もっと勉強してみたい

状態マシン、状態機会、ステートマシン,,,,,,
どれが正しいんですか!!!!!!!

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?