ホーム自己紹介ブログ
NO.306
DATE2026. 04. 02

『Webブラウザエンジニアリング』第12章を読みました。

以下の書籍を12章を読みました。
12章は難解でした。

Webブラウザエンジニアリング

Webブラウザは、現代のコンピューティング環境において欠かせない存在であり、最も広く使われているプラットフォームの一つです。本書は、その仕組みを実践的に学ぶための解説書です。実際にWebブラウザを構築する過程をたどりながら、レンダリング、HTMLパーサー、CSS、JavaScript、マルチスレッド対応、セキュリティモデル、アニメーションとコンポジット処理、ブラウザAPI、アクセシビリティなど、モダンなWebブラウザの主要な要素を順を追って解説していきます。 章ごとにコードを動かしながら、ブラウザに機能が積み重なっていく過程を通じて、ソフトウェアを成長させ改善していく経験を自然に体得できます。ブラウザ技術の研究者とChrome開発者による豊富な知見をもとに、Webの進化をたどりながら、手を動かしてブラウザの内部構造を深く理解できる一冊です。

oreilly.co.jp

1章から11章の感想については、以下で書いています。

  • 『Webブラウザエンジニアリング』第1~3章を読みました。 | ジブンノート - silverbirder.github.io
  • 『Webブラウザエンジニアリング』第4~6章を読みました。 | ジブンノート - silverbirder.github.io
  • 『Webブラウザエンジニアリング』第7~8章を読みました。 | ジブンノート - silverbirder.github.io
  • 『Webブラウザエンジニアリング』第9~10章を読みました。 | ジブンノート - silverbirder.github.io
  • 『Webブラウザエンジニアリング』第11章を読みました。 | ジブンノート - silverbirder.github.io

タスクとスケジュール

難解というのは、マルチスレッド関連の話が多く出ているためです。
本章の冒頭で、ブラウザで行う処理が増えてた結果、描画が遅くなってきました。
そこで、行うべき処理(実行可能な関数)をタスクと定義し、優先度を決めて処理する(task_runner)という考えになりました。

タスクは先入れ先出しを採用し、メインループ内で常にタスクを実行します。
タスクの追加には、schedule_task という関数実行により追加されます。
タスクのスケジュールとして良い例である settimeout を実装します。

settimeout を実行すると、Python の threading.Timer で指定時間後に schedule_task でタスクを積むという感じです。
その後、メインループ内で積まれたタスクが実行されるという流れです。

threading による処理を行うため、排他制御が必要になってきます。
タスク実行するときには、タスクをロックし、終わったらリリースする、そういうよくある排他制御を行います。

settimeout ができると、次は XMLHttpRequest の非同期処理も実装します。
こちらの処理は、関数処理を待たないように新しくスレッドを立ててメインプロセスを止めないようにします。
スレッドの処理が終わったら、schedule_task で完了内容を伝える、という具合です。

ここまでは、まだ理解できる範囲でした。

プロファイリングとダーティビット

ブラウザは、描画速度に 60fps を目指して処理を終わらせる必要があります。
おもちゃの私たちのブラウザでは、30fps (33ミリ秒)を目指します。
で、実際に chrome://tracing でプロファイリングすると、タブ(ページ)のラスタライズと描画に60msを超えて予算オーバーとなりました。

ここからが頭が痛くなってくるのです...。
描画速度を早めるための、パフォーマンスチューニング です。

2つほどトピックがあり1つ目がダーティビットです。
ダーティビットとは、何かデータが書き換わったら更新が必要と示すフラグのことです。
このフラグのON/OFFを最適化することで、不要な処理をスキップして早くするのです。
ただ、この ダーティビットのフラグ制御 が混乱します...。
ピタゴラスイッチみたいに、どれを押したらどれが動くのかを把握しなければいけません。
これでうまくできていないと、なぜか描画されないことになったり、過剰に描画したりします。

マルチスレッド

2つ目のトピックは、マルチスレッド化です。
スレッドを2つに分離することで、並列処理による高速化を図ります。
スレッドは、ブラウザスレッドとメインスレッドの2つに分けられました。
ブラウザスレッドは、ラスタライズや描画、クロームUIのインタラクション制御などを受け持ちます。
メインスレッドは、タブごとに増えていくページ用のスレッドです。
スクリプトの実行やレンダリング、イベントハンドラ処理など、ページの行うべき処理を担います。

複数のスレッドを並列で処理する際、ブラウザスレッドからメインスレッドへ通信したい場合は、
task_runner を通してタスクベースでやりとりします。
schedule_task でタスクを積むのです。

これらを踏まえて、ブラウザスレッドからタブへの参照を撤廃し、逆もまた然りです。
そのかわり、タスクベースでやりとりを切り替えます。

メインスレッドでは、HTMLの更新やスタイルの更新などでディスプレイリストが更新されます。
ディスプレイリストが変わると、ラスタライズと描画をブラウザスレッドに処理してもらう必要があります。
そこで、Commit と呼ばれる ラスタライズと描画に必要な情報(スクロール量、高さ、ディスプレイリストなど)を ブラウザスレッドに手渡ししています。
ただし、相互のデータアクセスをするのはNGなので、ディスプレイリストなどはコピーしたデータを送るようにして、元データも消すみたいなことをします。

他には、JavaScriptの処理が非常に遅い場合にスクロールができない問題を対処するため、
メインスレッドでやっていたスクロール処理をブラウザスレッドでも行うようにしています。(?)
スクロールオフセットを、メインスレッドもブラウザスレッドもディスプレイリストを参照して処理するようです。(?)

また簡単に書いていますが、このマルチスレッドにおいても、ダーティビットがたくさん出ます。
どういうときに、ラスタライズすべきか、アニメーションすべきか、描画すべきか、など結構出ます。
この章を3回ぐらい読み直したのですが、完璧に理解するのが難しく(トレースするのがしんどい)ので、なんとなく読んで終わりました。

強制スタイル、強制レイアウト

マルチスレッドを採用することで、高速化できました。
メインスレッドをさらに、用途別にスレッドを分けることで高速化できるのでは?という話題(?)がありました。
ただ、実態としてはやっていないようです。
というのも、メインスレッドでは JavaScript API のスタイル参照機能があるためです。
getComputedStyle のような機能は、スタイル情報を計算する必要があり、 getBoundingClientRect のような機能は、レイアウト情報を計算する必要があります。
これらの機能は、メインスレッドの処理に強く依存してしまうため(?)、別スレッドとして高速化するのは難しい(??)みたいです。

終わりに

12章は、何度も読んだのですが難しかったです...。

書籍レビュー

-

読者になる

|

シェアする

|

silverbirders

silverbirder

Webソフトウェアエンジニア

ブログを応援する

この記事がよかったら、お布施という形で応援してもらえるとうれしいです。

おふせぼたん

※ ログイン不要で投稿できます。

※ 同じブラウザから投稿を削除できます。

0

読み込み中...

前の記事へ

関連する記事

タグ「書籍レビュー」の記事

『Webブラウザエンジニアリング』第11章を読みました。

以下の書籍を11章を読みました。 11章はかなり奥が深いので、1つの章のみの感想になります。 https://www.oreilly.co.jp/books/9784814401574/ 1章から10章の感想については、以下で書いています。

2026年03月29日

書籍レビュー
『Webブラウザエンジニアリング』第9~10章を読みました。

以下の書籍を9章から10章まで読みました。 https://www.oreilly.co.jp/books/9784814401574/ 1章から8章の感想については、以下で書いています。 『Webブラウザエンジニアリング』第1~3章を読み

2026年03月27日

書籍レビュー
『Webブラウザエンジニアリング』第7~8章を読みました。

以下の書籍を7章から8章まで読みました。 https://www.oreilly.co.jp/books/9784814401574/ 1章から6章の感想については、以下で書いています。 『Webブラウザエンジニアリング』第1~3章を読みま

2026年03月25日

書籍レビュー
← ブログ一覧へ