Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ブラウザの作り方

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

 ブラウザの作り方

Avatar for Keiya Sasaki

Keiya Sasaki

January 25, 2021
Tweet

More Decks by Keiya Sasaki

Other Decks in Technology

Transcript

  1. 実装状況
 • display … block, inline • background, color •

    width, height, margin, border, padding • font-family(local fontのみ) • font-size, font-weight, font-style • line-height • Scroll • Text周り(改行など)
  2. ブラウザの仕組みを知る
 • Populating the page: how browsers work
 ◦ こっちはブラウザの詳しい説明というよりはWeb

    Performanceを中心にして 
 ブラウザの仕組みを解説している 
 ◦ 最初にこっちを読むと下の記事が読みやすいかも 
 • How Browsers Work: Behind the scenes of modern web browsers
 ◦ Parserの仕組みからブラウザの詳細な仕組みについて解説している 
 

  3. ブラウザを作る
 • Let's build a browser engine! を読む
 ◦ Servoのメンバーの人が書いた記事

    
 ◦ Rustを使って実装していく
 ◦ Part1 ~ Part7まである
 ◦ 機能を絞っているので、テンポ良く実装できる 
 ◦ HTML・CSS のParse → Style → Box Model → Layout → Paint 
 ◦ Paint部分は画像として出力している 
 • W3C を読む
 ◦ CSSなどの仕様
 • WHATWG を読む
 ◦ DOM, HTMLなどの仕様

  4. 仕様の読み方(W3C)
 • Jxckさんの WEB技術の調査方法 の W3C/WHATWG のセクションを
 読むと読み方がわかってくる
 • W3Cの

    Levels, snapshots, modules… を読むと、どのように仕様が
 策定されていくかがわかる

  5. 参考になるリポジトリ
 • Servo
 ◦ `/components` 配下に各moduleが入っている
 • twilco/kosmonaut 
 ◦

    Servoをインスパイアしたブラウザエンジン 
 ◦ Let's build a browser engine!を参考にしている
 ◦ parserとかはservoで使われているparserを使っている 
 • maekawatoshiki/naglfar
 ◦ 日本人の方が作っているブラウザ 
 ◦ Let's build a browser engine!を参考にしている
 • keiya01/kamaitachi
 ◦ 今作っているやつ

  6. ブラウザの仕組み
 Parse
 Style
 Layout
 Paint
 HTML・CSSを Tree構造のデー タに変換する
 CSSルールをDOM と紐付ける(レン

    ダーツリー)
 Styleをもとに、
 それぞれの要素の Positionや高さ、
 幅を計算していく
 Layoutで計算した データをもとに
 描画していく

  7. HTML Parse
 1. 1文字づつプログラム中の文字を読み込んでいく
 2. `<`が見つかったら、elementとして、タグの中身を読み取っていく
 ◦ `<div></div>`の場合、`<`が見つかると、中身を1文字づつ`>`にぶつかるまで 
 探索していく


    3. `<..>`の中身を読みよったら、次に子要素を読み取っていく
 ◦ `<div><p>children</p></div>`の場合、`<p>`を同じように読み取っていく 
 4. 子要素を読み取ったら最後に`</`があるかを確認する
 ◦ HTMLは後方互換性のために基本的に構文エラーは起きない 
 ◦ そのため、`</`がなかったとしてもそのまま処理を続ける 
 5. Text Nodeが存在する場合は、`<`に達するまで文字を読み取っていく

  8. CSS Parse
 1. 先頭に`.`が見つかればclass、`#`が見つかればid、使用可能な文字列であれば
 要素名としてparseし、selectorsに格納する
 2. `{`にぶつかると宣言ブロックの処理に移る
 3. ここでは`property: value;`のペアをそれぞれparseし、declarationsに格納する


    4. CSSには詳細度(specificity)という、どのCSSルールを適用するかを決める
 重み付けのようなものがあるのでそれを求める
 ◦ idをselectorに持つ宣言はclassよりも優先されるといったようなもの 
 5. 詳細度をもとにselectorsをsortしておく

  9. Style
 1. HTMLのparseで得たDOMとCSSのparseで得たCSSOMを
 Root Nodeから順に見ていく
 2. CSSのRulesは詳細度によってsortされているので、
 NodeとSelectorが最初にmatchした要素を取得する
 3. matchしたCSS

    Rulesを詳細度の低いものから高いものへソートし、
 HashMapにpropertyをkeyとしてvalueをinsertしていく
 ◦ これにより、先にinsertされた値は、後にinsertされる詳細度の高い値で 
 上書きされる
 4. ここでは省略するが、他にもUseragent Stylesheetとのmergeや、
 継承、computed valueなどの処理もここで行う

  10. Layout
 1. StyleTreeからdisplayの値を受け取り、Box(display)ごとに分類する
 ◦ BlockNode, InlineNode, TextNodeなど 
 ◦ 分ける理由は、Boxによってpositionが異なるから

    
 ◦ 例えば、Blockは縦方向に配置されるが、Inlineは横方向に配置される 
 2. BlockNodeの場合、width => position => children => heightの順で
 計算していく
 3. InlineNodeの場合は、扱い方が2種類ある。
 ◦ BlockNodeの中にInlineNodeのみが含まれている場合(<span>abc<em>def</em></span>) は、そのまま処理を進める
 ◦ BlockNodeの中にInlineNodeとBlockNodeが含まれている場合、各Boxは同じTypeのBoxし か含めることができないので、InlineNodeをAnonymouseBlock 
 というBoxでラップする。これにより横に配置する処理を行いやすくする。 

  11. Paint
 1. 最初にLayout TreeからDisplayListを作成する
 ◦ DisplayListはbackground-colorやcolorなどの情報を切り出しておき、 
 レンダリング処理を行いやすくする 
 ◦

    DisplayListとして切り出しておくことで、colorの変更などが起こったときに、DisplayListを 探索すれば簡単にcolorの変更ができたりする 
 2. DisplayListからItemを取り出し描画していく