Share
Embed
Transcript
94 slides
-
ブラウザの構成要素 • ブラウザは大きく4つの柱でできている。 ブラウザのインタフェース アドレスバーとか戻るボタンとか • レンダリングエンジン / ネットワーク /
JavaScript エンジン / データストレージ -
ブラウザの構成要素 • ブラウザは大きく4つの柱でできている。 ブラウザの中核、各コンポーネントに指示を 出す、コンポーネントの動きを把握してスケ ジュールするなど • レンダリングエンジン / ネットワーク
/ JavaScript エンジン / データストレージ -
ブラウザの構成要素 • ブラウザは大きく4つの柱でできている。 データの保存をする所 Cookie, localstorage とかそのへん • レンダリングエンジン /
ネットワーク / JavaScript エンジン / データストレージ -
Before ブラウザ • 統一されたフォーマットもなく、各々が資料を書き、それを 送って閲覧するような状況だった... • Tim Berners Lee 氏が「待てよ?インターネットの上で統一さ
れたドキュメントフォーマットと統一されたアクセス形式と統 一されたアクセス方法があれば、情報共有が簡単になるので は・・・?」と思った。 -
最初期のブラウザ • 統一されたドキュメントフォーマット => HTML • 統一されたアクセス形式 => URL •
統一されたアクセス方法 => HTTP -
1990年代: ブラウザ戦争 • ビッグカンパニーも黙っていない。 • IBMが WebExplorer を開発し、その後 Microsoft が
Internet Explorer を開発する。 • Mosaic は NetScape 会社を立ち上げ、 Navigator という名前で開発する。 • 第一次ブラウザ戦争が勃発する。 -
1990年代: ブラウザ戦争 • JavaScript もこの頃から開発されだす(1995年) • HTTP Cookie などの仕組みも開発される •
HTTPS などの暗号化の仕組みもこの頃から -
1990年代: ブラウザ戦争 • 機能の拡充が進んでいく一方でブラウザ戦争は悲劇ももたらした。 • 過激な差別化と機能拡充が進む中で独自拡張にはしることも増えていく • JScript と呼ばれるほとんど JavaScript
と同じような機能を持ったスクリプト言語が Internet Explorer に実装される • JavaScript で Style を決められる JavaScript Style Sheet も提案されるが、仕様決め きれないうちに終わるなど。 -
1990年代: ブラウザ戦争 • 最終的に第一次ブラウザ戦争はマイクロソフトが勝利する • OSにブラウザが同梱される事で NetScape のブラウザよりもユーザー数を伸ばし、 寡占状態が作られてしまう。 •
NetScape 側はユーザー数の獲得には失敗したものの、 OSS 化してブラウザの技術 を後世に残し、 Mozilla という企業に形を変えて存続する -
2000年代: Google Chrome の登場、ス マートフォンの登場 • Mozilla が満を持して FireFox を開発して、リリースする。
• 今まで Internet Explorer 一強状態だったが、仕様に忠実であり、高速に動き、タブ機能や拡張機能を備えた FireFox がユーザー数を抜く • 2000年代後半になるとプレイヤーが変わる。 • まず Google が JavaScript と動的な HTTP リクエスト(いわゆる Ajax) を組み合わせる事でこれまでの HTML、 CSS、 JavaScript という技術だけでインタラクティブなアプリケーションをウェブ上で作れることを 実践する。 • 次に Google が Chrome をリリースする。 -
2000年代: Google Chrome の登場、ス マートフォンの登場 • 2000年代の前半から後半にかけて起きたのは、ウェブ上でインタラクティブなアプリ ケーションを作るという技術的なパラダイムシフト • ブラウザ上で
JavaScript を中心にアプリケーションを作る機会が増えた。 • 結果として、アプリケーションの実行速度に直結する JavaScript の実行環境にも見直し が入る。 • 各ブラウザのJavaScript Engineに Just-in-time (JIT) Compiler と呼ばれる実行中に最適 化する機能が導入されていく -
2010年代: HTML5ブームとスマートフォン ネイティブアプリ • 2010年からはアプリケーションをウェブでより効率的に、新し く作ろうとするブームが到来した。 • ブラウザにもスマートフォンで見れるアプリケーションを作る 流れが到来した。 •
このあたりからネイティブアプリとブラウザ両方で同じような 機能を提供するようになる -
2010年代: HTML5ブームとスマートフォン ネイティブアプリ • アプリケーションの作り方がネイティブアプリの作り方に近くなっていった。 • クライアント内で Local Storage や
Session Storage といったクライアントのストレー ジを使おうとしたり、オフラインでも動作するようにブラウザが進化していった。 • この頃に Network にも進化が訪れる。ブラウザが利用するコンテンツがよりリッチに なり、アプリケーションもできることが増えていくと、ネットワークの利用率が上 がっていく • HTTP/2 といった効率的にリクエストする方法が出てくる。 -
2020年代 — パフォーマンスと互換性 • Edge が Chromium ベースに — エンジンは
Chrome系 / Safari系 / Firefox系 の3つへ • Core Web Vitals — ユーザー体験の数値化 • HTTP/3 — TCP すら捨てた -
ブラウザ歴史まとめ • この歴史は全て「困った → 解決した → でもまた困った」の繰り返し • このようにアプリケーションを作る方法が確立されていったり、新し い技術的な転換が起きるとその都度ブラウザは技術的な進化を遂げて
きた。 • 今日のモダンなブラウザはこのような技術的進化が日進月歩で行われ ている。 -
遅いはずのJavaScriptが高速になるまで • JavaScript はプログラミング言語の種類で言うと「動的型付け言語」であり「プロ トタイプベースの言語」になる • 対義語(?)で言うと「静的型付け言語」であり「クラスベースの言語」、今で言 う Go, Java,
Rust, TypeScript などなど • 実は圧倒的に速度に差がある • 実行時にコンパイル、解析しながら動作するのでどうしても初期速度は劣る • しかし、今では高速な言語として認識されている -
そもそものはじまり • ブラウザでも動的な処理をさせたい!!!したい!!!! • 静的 => HTML / CSS 宣言的
• 動的 => ユーザーの操作に合わせた動き 逐次操作的 • Netscape Navigator が 1995年に 「JavaScript」を開発 -
そもそものはじまり • Brendan Eich 氏が1995年に Self, Scheme, Java などのそれぞ れのエッセンスを持ってきて7日間で作成
• Javaっぽいスクリプト言語なので「JavaScript」 • でもその後 Microsoftから JScript という似ているようでちょっ と違う言語ができ、カオス状態になる -
そもそものはじまり • 仕様を決めて、Microsoft陣営の独自拡張から守ろう!!! • 一旦 W3C (Tim Berners=Lee氏)の元へ • ティム・バーナーズ=リー
< No... • W3C は宣言的なHTML, CSSは対象だが、逐次操作的な言語みたい なのは同じWebの仲間ではないと一蹴 -
そもそものはじまり • 一同一路、ヨーロッパへ。。。 • ECMAという仕様化団体に行き着く • ECMAで仕様を決めて国際標準として展開 • 仕様上はECMAScript 、一般呼称は
JavaScript として晴れて標 準化の仲間入りを果たす -
そもそものはじまり • これはこれで1つのドラマ • JavaScript は Netscape Navigator で開発されたが、 Microsoft
から似たようなのを作られ、守るために仕様を決めて国際標準を 目指した。しかし W3C はそれを拒否、泣く泣く ECMA に仲間 入りを果たした。 • なので仕様上の呼称は ECMAScript -
1995年から2000年になるまで • そもそも速度は求められていなかった • 遅くてもいいから動的に動くものであればよかった • いわゆるインタープリタと呼ばれるものだけで動いていた • そこから1996年に SpiderMonkey
と呼ばれるバーチャルマシンで動作す るようになった。 • このあたりのインタープリタとバーチャルマシンはデモで解説します。 -
2000-2010年にかけて • 世界が変わった • JavaScriptでアプリケーションを作るようになった (Gmail, Google Maps, Google Docs)
• スクリプト言語は遅くても良いではなくなった。 -
2000-2010年にかけて • Self という言語がやっていた方法で高速化を試みた • 型を推定する、動作を直接アセンブリに変換するなどの方法 • これを Just In
Time Compiler (JIT) と呼ばれ、広く採用される ことになった • これもデモで紹介します。 -
JavaScript のドラマ • 最初は機能による差別化、次に共通仕様化がある • ブラウザ戦争の裏側では常に差別化と仕様化が交互に進んでる • さらにその奥に速度戦争がある • パフォーマンスを如何に上げるか
• JavaScript は20年の蓄積を経て、今やスクリプト言語では最速の位置 -
レンダリングエンジン • 指定されたコンテンツを描画するもの • ここでは主に HTML を描画する時の流れで解説するが、本来は HTML に依らず、コンテンツを描画する。 Render
Graphic Interface 特にここを深堀りする -
レンダリングプロセス • HTML のレンダリングは "動的に" レンダリングする。 • JavaScript やユーザー入力、アニメーションなどでレンダリン グが更新される。
Initial Render 更新 更新 更新 更新 -
レンダリングプロセス • コンテンツが動的に更新されるということがウェブの特徴 • そのためにいくつかの中間表現を持っている • Parse → Style →
Layout → Paint → Composite -
HTML Parse <div> <p> hello </p> <p> world </p> </div>
Parse DIV P TEXT P Document Tree HTML Body Div • タグをネストして表現 P TEXT • 木構造という形でデータ構造として 表現される。 P TEXT -
DOM Document HTML • Document Object Model • ブラウザ内でのHTMLの内部表現 Body
Div • であり、かつ JavaScript で操作できるデータ構造 var div = document.body. rstChild; var p2 = div.childNodes[1]; p2.appendChild(document.createElement("span")); P TEXT P bindings fi TEXT JavaScript Engine -
Style Document HTML • DOM を作ったらそれに Style を 当てていく Body
Div p { color: red } • P TEXT Style P TEXT hello world -
Style • セレクタ • スタイルを当てる際の直接的なルールを記述し て内容を含めたもの p { color: red;
} #test { border: red 2px solid; } .foo { background-color: skyblue; } -
Style • CSS (Cascading Style Sheets) • セレクタを複雑に指定できる ちなみに複雑な指定をすればするほど複雑な計算が必要なので遅い。 •
セレクタは被ることがある • 被ったら詳細度で決まる div:not(.foo) > p:nth-of-type(2n) { color: red; } p{ color: blue; } -
Style • セレクタマッチング • 各要素のCSSのセレクタを一つ一つ見ていってスタイルを反映する • イメージとしてはアンケート入力フォームに近い Margin ✔ top:
20px • ✔ family: serif left: style: bottom: size: Color ✔ Font 255,255,255,0 Padding top: left: bottom: -
Style • カスケーディング • アンケート入力フォームの中で空欄を見つけて補う処理 • 親の要素が持っていたら子に適用していく Margin ✔ top:
20px Font ✔ family: serif left: style: bottom: size: Color ✔• 255,255,255,0 Padding top: left: bottom: 埋まってないところをチェック Margin ✔ ✔ ✔ top: 20px left: 20px bottom: 30px Color ✔ 255,255,255,0 Font ✔ ✔ ✔ family: serif style: normal size: 10 Padding ✔ ✔ ✔ top: 20px left: 20px bottom: 20px 親からもらえるところは借りてくる -
Style div:not(.foo) > p:nth-of-type(2n) { color: red; } Parse/Rule Style
Rules Style StyleRules Rules p{ color: blue; } CSSもパースし、スタイルのルールセットを作る。 -
Style Style Rules Style Rules Style Rules Document Document Computed
Styles HTML HTML Computed Styles Body Body Computed Styles Div Div Computed Styles P P Computed Styles TEXT TEXT P P TEXT Computed Styles Computed Styles TEXT Computed Styles -
Style Style Rules Style Rules Style Rules Document Document Computed
Styles HTML HTML Computed Styles Body Body Computed Styles Div Div Computed Styles P P Computed Styles TEXT TEXT P P TEXT Computed Styles Computed Styles TEXT Computed Styles ルールを DOM に適用して Computed Style を作る -
Style Document Computed Styles HTML Computed Styles Body Computed Styles
Div Computed Styles P Computed Styles TEXT P Computed Style { fontWeight = ... marginLeft = ... outline = ... transform = ... background = ... } Computed Styles Computed Styles TEXT Computed Styles フォントや背景などのスタイル情報をDOMに付与する -
Layout • 一つ一つの要素はスタイルをもっていても、そ れがどこに配置されるか、どれくらいのサイズ なのか、という場所の情報は持っていない。 • HTMLの構造と Style の情報を基に場所とサイ ズを計算する処理が
Layout • 親から再帰的に辿って Layout 処理を行う -
Layout 高さ・幅・位置を計算 Document HTML • 親から子どもに再帰的に計算を していく Body Div P
TEXT P TEXT • 子どもの高さ・幅を計算したら 親は子どもの累積された高さ・ 幅と自分自身の高さ・幅にマー ジンを加えて高さを計算する -
Paint • DOMの要素の順番ではなく、 z-index 等を 使って後ろの要素と前の要素を入れ替えるこ とができる。 <div class="yellow"></div> <div
class="green"></div> <style> .yellow { z-index: 2; ... } .green { z-index: 1; ... } </style> -
レンダリングエンジン のドラマ • 途中で描画が変わることを前提としたパイプラインになっている • であるが故に初期の方の処理に無理矢理 (document.write) とかでHTMLごと書き換えると全て がやり直し •
document.write 使えなくなったのはそういう経緯 • パイプラインの後ろの方でやればやるほど描画へのインパクトは少ない。 • width,heightを変える => Layout に影響 • opacity, transformを変える => Compositeに影響 -
HTTP/1.1 — 接続を維持する • 1997年。接続の維持がデフォルトになった • しかし、1本の接続で1つのリクエストしか 処理できない • 1つのリクエストが返るまで、
次のリクエストは送れない。 • ブラウザは5〜6本の接続を並列で張ることで対処した。 -
HTTP/2 - 多重化 • Google が先に SPDY を作った。 「標準化を待てない」と。 •
それが標準化されて HTTP/2 に なった(2015年)。 • 1本の接続の中に ストリーム を 100本作れるようにした。 -
HTTP/2 の内部 • TCP 接続は1本だが、中で HEADER フレームや DATA フレームが行き交 う。
• HTTP レベルの HoL は解消された。しかし... -
HTTP/3 — QUIC • UDP の上に QUIC という新しいプロ Client トコルを作った。これも
Google が 1: (data) 先行し、後から標準化。 • 到達保証あり。ただしストリーム単 2: (data) 3番だけパケロス が発生 位で独立。1つロスしても他は止まら ない Server ✕ 3: (data) 4: (data) クライアント側で3が 来てないことを タイムアウトで検知 ACK: 1,2,4 (3が未達) 3番だけ再送 3: (data) -
HTTP/3 — QUIC • • 暗号化と接続確立を保証 安全性と性能を両立させた Client Server QUIC接続確立
(TLS 1.3 ハンドシェイクを内包) QUIC Initial パケット (Client Hello を含む) QUIC Initial / Handshake パケット Server Hello、Encrypted Extensions、 Certificate、CertificateVerify、Finished QUIC Handshake パケット (Client Finished を含む) QUIC + TLS 1.3 接続確立 アプリケーションデータ アプリケーションデータ データ転送 -
HTTP のドラマ • とりあえずつながる • たくさんリソースが増える(画像、動画、アプリケーション) • 接続が一本だと足りなくなる • 並列に接続するが、今度はブロッキングが起きる
• TCPレベルでブロッキングを解消、一方でTCPレベルのブロックは健在 • TCPをやめる、QUICという形で新しいプロトコルを開発 => HTTP/3 へ