Web エンジニアリング基礎 -- Part02 TS のメリットとブラウザのレンダリング詳細
Tags: webdev, html, dom, japanese
Published: 2023-01-01 09:28:57


Part01 の続きとしてフロントの基礎を説明できるようにする。

# TS のメリット

https://zenn.dev/rio_dev/articles/c0da74ae28bdcd#typescript%E3%81%8C%E8%A7%A3%E6%B1%BA%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%92%E8%AA%AC%E6%98%8E%E3%81%9B%E3%82%88%E3%80%82

自分の実感から考える。

VScode を使っていなくても、文法的に間違ったコードを書いたときに、TS から JS にコンパイル(変換)する段階でエラーを出してくれる。

なので時間のかかるアプリのビルド処理の前にエラーが出ることで、コードの修正待ち時間が短くなると解釈した。

また、VSCode を使った場合は引数が足りない場合や、引数や返り値の型が違う場合、カッコが足りない場合などを書いた瞬間に検知してエラー表示してくれる。

なのでより直ぐに開発者が気づいて修正できて、開発速度が向上すると解釈する。

---

# ブラウザレンダリング

https://zenn.dev/rio_dev/articles/c0da74ae28bdcd#%E2%98%86%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF%E3%82%92%E8%AA%AC%E6%98%8E%E3%81%9B%E3%82%88%E3%80%82

この記事だけではリソースの取得意向があまり理解できなかったので

https://zenn.dev/ak/articles/c28fa3a9ba7edb#%E5%85%A8%E4%BD%93%E5%9B%B3

akimuu さんの記事も参考にする。

https://developer.mozilla.org/ja/docs/Web/Performance/How_browsers_work

言葉が難しいが、MDN が一番詳しく書いてあるので一番正しい情報として参考にする。

http:// kaede . dev にブラウザで GET リクエストをして、帰ってきた HTML を表示する流れを説明する。

---

## 名前解決して TCP or TLC で経路確立

まずは http:// kaede . dev のような文字列の URL を
割り当てられている 10.12.101.11 のような数値の IP アドレスに変換する。これを名前解決という。

https://developer.mozilla.org/ja/docs/Web/Performance/How_browsers_work#tcp_%E3%83%8F%E3%83%B3%E3%83%89%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF

名前解決で IP アドレスがわかってから TCP/TLC で通信経路を確立する。

https://zenn.dev/ak/articles/c28fa3a9ba7edb#html%E3%81%AE%E8%A7%A3%E6%9E%90

---

## バイトコードでレスポンスを受け取る

（予想）その後レスポンスのボディとして　HTML/CSS/JS が固まったバイトコードのデータが返ってくる

---

## トークンへの変換

https://zenn.dev/ak/articles/c28fa3a9ba7edb#tokens%E3%81%AB%E5%A4%89%E6%8F%9B

そのバイトコードのデータを一度トークンというざっくりしたものに変換する。

トークンはスタートタグ `(<html>,<h1>)` やエンドタグ `(</html>,</h1>)` やキャラクター(タグの中身に書かれた文字列)などがある。

---

## ノードへの変換

次にトークンをざっくりとした逆さの木のような構造ができている、ノードに変換する。

---

## DOM への変換

そこからノードを Document Object Model こと DOM に変換する。

https://developer.mozilla.org/ja/docs/Web/Performance/How_browsers_work#%E3%83%97%E3%83%AA%E3%83%AD%E3%83%BC%E3%83%89%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%8A%E3%83%BC

---

## プリロードスキャナでの CSS DOM の構築

その途中で style　や script の css と js のタグを見つけると、
並行して CSS Object Model の構築、次に JS のダウンロードが始まる
これをプリロードスキャナという。

https://zenn.dev/ak/articles/c28fa3a9ba7edb#cssom%E3%81%AE%E6%A7%8B%E7%AF%89

CSS DOM では親の要素を引き継ぎ or 上書きで子供の要素を作っていく。

https://zenn.dev/ak/articles/c28fa3a9ba7edb#%E5%AD%97%E5%8F%A5%E8%A7%A3%E6%9E%90

---

## JS の AST への変換とコンパイルと実行

JS は HTML と同じようにトークンに変換する。
次に抽象解析ツリー (Abstract Syntax Tree)に変換する。
そして Chrome v8 などの JIT コンパイラでコンパイルして、バイトコード(機械語)に変換する。

https://dev.to/lydiahallie/javascript-visualized-the-javascript-engine-4cdf

この記事のインタプリンタの仕事は、現在は JIT コンパイラがしているようだ。

最後に CPU　がバイトコードを実行して JS の処理が実行される。

---

## レンダーツリーの作成

JS の実行前に行われるかは未確認。

HTML の DOM と、CSS の　CSSOM 
これらをマージして body の中身の描画する要素のタグとスタイリングだけをまとめたレンダーツリーというものを作る。

---

## レイアウトとして viewport を計算する

https://zenn.dev/ak/articles/c28fa3a9ba7edb#layout

一番親要素の width の 100% の基準となる、viewport を読み込む。

---

## ペイントとしてエレメントを描画する順番を決める

背景色->背景イメージ->ボーダー->中身

この順番でセットして、中身を 

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context

* z-index
* position: fixed, sticky 
* opacity
* transform

などの重ね合わせの順序が変わる CSS プロパティを計算した上で描画する。

---

## コンポジットとしてレイヤーツリーをコンポジタースレッドに渡す

ペイントで決めたことを元にブラウザのメインスレッドはレイヤーツリーを生成する。

（予想）ペイントで各エレメントの重ね合わせの細かい情報を洗い出したので、1~4 層のような大きなまとまりにまとめる。これがペイント後とレイヤーツリーの違い。

---

## ラスターツリーで最終加工したものを GPU に渡して画面描画。

レイヤーツリーをメインスレッドからコンポジタースレッドに渡して、分割して viewport の範囲を優先と付けてラスタースレッドというものに渡す。
ラスタースレッドがレイヤーツリーを何にしているかは不明。

コンポジタースレッドがラスタースレッドで処理された描画情報を GPU 
に渡して、画面が描画される。

以上。

---

## 今後やること

https://zenn.dev/rio_dev/articles/c0da74ae28bdcd#%E2%98%86%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF%E3%82%92%E8%AA%AC%E6%98%8E%E3%81%9B%E3%82%88%E3%80%82

フロントエンドの項目、あと 16 個！