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

ブラウザの作り方

 ブラウザの作り方

Keiya Sasaki

January 25, 2021
Tweet

More Decks by Keiya Sasaki

Other Decks in Technology

Transcript

  1. ブラウザの作り方

    Keiya Sasaki 2021/01/25


    View Slide

  2. ➔ Sasaki Keiya

    ➔ 大学4年生

    ➔ 4月からIT企業で

    フロントエンドエンジニア

    ➔ TypeScript・Rust

    ➔ Twitter: _keiya01

    ➔ Github: keiya01


    View Slide

  3. 話すこと


    View Slide

  4. 1. 実装状況

    2. 実装方法

    3. チュートリアル

    4. まとめ


    View Slide

  5. 実装状況


    View Slide

  6. 実装状況

    ● display … block, inline
    ● background, color
    ● width, height, margin, border, padding
    ● font-family(local fontのみ)
    ● font-size, font-weight, font-style
    ● line-height
    ● Scroll
    ● Text周り(改行など)

    View Slide

  7. View Slide

  8. 実装方法


    View Slide

  9. 手順

    1. ブラウザの仕組みを知る

    2. ブラウザを作る


    View Slide

  10. ブラウザの仕組みを知る

    ● Populating the page: how browsers work

    ○ こっちはブラウザの詳しい説明というよりはWeb Performanceを中心にして

    ブラウザの仕組みを解説している

    ○ 最初にこっちを読むと下の記事が読みやすいかも

    ● How Browsers Work: Behind the scenes of modern web browsers

    ○ Parserの仕組みからブラウザの詳細な仕組みについて解説している


    View Slide

  11. ブラウザを作る

    ● Let's build a browser engine! を読む

    ○ Servoのメンバーの人が書いた記事

    ○ Rustを使って実装していく

    ○ Part1 ~ Part7まである

    ○ 機能を絞っているので、テンポ良く実装できる

    ○ HTML・CSS のParse → Style → Box Model → Layout → Paint

    ○ Paint部分は画像として出力している

    ● W3C を読む

    ○ CSSなどの仕様

    ● WHATWG を読む

    ○ DOM, HTMLなどの仕様


    View Slide

  12. 仕様の読み方(W3C)

    ● Jxckさんの WEB技術の調査方法 の W3C/WHATWG のセクションを

    読むと読み方がわかってくる

    ● W3Cの Levels, snapshots, modules… を読むと、どのように仕様が

    策定されていくかがわかる


    View Slide

  13. 1. 実装したい機能をMDNで検索

    2. MDNの下の方にSpecificationsが

    出てくるので新しそうなやつを開く

    3. ざっと読んで、リンクを辿っていく

    4. 何となく理解したら、Servoなどの既存
    のリポジトリの実装をみてみる

    5. 実装する

    進め方


    View Slide

  14. 参考になるリポジトリ

    ● 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

    ○ 今作っているやつ


    View Slide

  15. チュートリアル


    View Slide

  16. ブラウザの仕組み

    Parse
 Style
 Layout
 Paint

    HTML・CSSを
    Tree構造のデー
    タに変換する

    CSSルールをDOM
    と紐付ける(レン
    ダーツリー)

    Styleをもとに、

    それぞれの要素の
    Positionや高さ、

    幅を計算していく

    Layoutで計算した
    データをもとに

    描画していく


    View Slide

  17. HTML Parse

    1. 1文字づつプログラム中の文字を読み込んでいく

    2. `○ ``の場合、``にぶつかるまで

    探索していく

    3. ``の中身を読みよったら、次に子要素を読み取っていく

    ○ `children`の場合、``を同じように読み取っていく

    4. 子要素を読み取ったら最後に``があるかを確認する

    ○ HTMLは後方互換性のために基本的に構文エラーは起きない

    ○ そのため、``がなかったとしてもそのまま処理を続ける

    5. Text Nodeが存在する場合は、`

    View Slide

  18. CSS Parse

    1. 先頭に`.`が見つかればclass、`#`が見つかればid、使用可能な文字列であれば

    要素名としてparseし、selectorsに格納する

    2. `{`にぶつかると宣言ブロックの処理に移る

    3. ここでは`property: value;`のペアをそれぞれparseし、declarationsに格納する

    4. CSSには詳細度(specificity)という、どのCSSルールを適用するかを決める

    重み付けのようなものがあるのでそれを求める

    ○ idをselectorに持つ宣言はclassよりも優先されるといったようなもの

    5. 詳細度をもとにselectorsをsortしておく


    View Slide

  19. 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などの処理もここで行う


    View Slide

  20. ElementにMatchしたCSS Rulesを詳細度の低いものから高いものへ
    ソートし、HashMapにinsertしていく

    View Slide

  21. Layout

    1. StyleTreeからdisplayの値を受け取り、Box(display)ごとに分類する

    ○ BlockNode, InlineNode, TextNodeなど

    ○ 分ける理由は、Boxによってpositionが異なるから

    ○ 例えば、Blockは縦方向に配置されるが、Inlineは横方向に配置される

    2. BlockNodeの場合、width => position => children => heightの順で

    計算していく

    3. InlineNodeの場合は、扱い方が2種類ある。

    ○ BlockNodeの中にInlineNodeのみが含まれている場合(abcdef)
    は、そのまま処理を進める

    ○ BlockNodeの中にInlineNodeとBlockNodeが含まれている場合、各Boxは同じTypeのBoxし
    か含めることができないので、InlineNodeをAnonymouseBlock

    というBoxでラップする。これにより横に配置する処理を行いやすくする。

    View Slide

  22. BlockNodeの例


    View Slide

  23. AnonymousBlock

    Block(div)

    Anonymous Block

    Block


    View Slide

  24. Paint

    1. 最初にLayout TreeからDisplayListを作成する

    ○ DisplayListはbackground-colorやcolorなどの情報を切り出しておき、

    レンダリング処理を行いやすくする

    ○ DisplayListとして切り出しておくことで、colorの変更などが起こったときに、DisplayListを
    探索すれば簡単にcolorの変更ができたりする

    2. DisplayListからItemを取り出し描画していく


    View Slide

  25. DisplayList


    View Slide

  26. まとめ

    ● ブラウザの仕様はとても多い

    ● ブラウザを作り進めるにつれて無限に仕様が湧いてくる

    ● 一方で知らない世界を知れてとても楽しい(unicode, fontなど)

    ● 興味を持ってくれた方がいれば是非作ってみてください!


    View Slide

  27. ありがとうございました!


    View Slide