CLOUDFLARE WORKERS
Cloudflare の Kitesurf を、公開情報だけで作ってみた
Chromium を使わず、Rust で書いたブラウザエンジンを Wasm にして Workers の isolate で動かす。Cloudflare が 2026 年 8 月に発表した Kitesurf と同じ構成を、発表記事に名前が挙がっている部品だけで組んだものです。ソースコードは非公開なので、中身は見ていません。
以下の画像は全部、この Worker が Wasm の中で描きました。
3 つのブラウザで同じページを撮る
左が本物のブラウザ (Chromium)、中央が Cloudflare の 本物の Kitesurf、右がこの記事で組んだ疑似 Kitesurfです。3 枚は同じ時刻に撮っています — ja.wikipedia のトップページは日ごとに変わるので、別々に撮るとエンジンの違いとページの違いが混ざります。画像を押すと元の大きさで開きます。
撮影 2026-09-08 13:39 UTC。3 枚は並列に撮っているので、同じ時刻・同じ回線です。数字は撮影を頼んでから絵が返るまでの時間で、CPU 時間ではありません。下の「自分で試す」だけはその場で描きます。
ja.wikipedia.org
日本語の見出しと本文、2 カラム、写真 24 枚。CSS は 3 枚で 231 KB
https://ja.wikipedia.org/wiki/メインページ · 1000×780
Chromium202 KB
2437 ms
Kitesurf390 KB
9021 ms
疑似 Kitesurf366 KB
5434 ms
developer.mozilla.org
CSS 20 枚。本文中の map() が等幅で出ている。JS は 938 KB 実行してエラー 0 件
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map · 1000×780
Chromium60 KB
1069 ms
Kitesurf68 KB
9840 ms
疑似 Kitesurf57 KB
4144 ms
react.dev
SSG。ページの JS を実行して、React のハイドレーションが通った状態
https://react.dev/ · 1000×780
Chromium153 KB
1707 ms
Kitesurf84 KB
3985 ms
疑似 Kitesurf74 KB
8780 ms
todomvc.com (React の SPA)
HTML の中は空。見えているものは全部、ページの JS が描いたもの
https://todomvc.com/examples/react/dist/ · 1000×780
Chromium22 KB
1627 ms
Kitesurf91 KB
2704 ms
疑似 Kitesurf20 KB
2830 ms
自分で試す
好きな URL を入れてください。この場に画像が出ます。
外部 CSS と画像は Worker が取ってきてエンジンに渡します。重いページは 10 秒ほどかかります。10 秒で 4 枚までにしています。
JavaScript も動く
ページの <script> を Boa (Rust で書かれた JavaScript エンジン) で実行しています。Workers は eval と new Function を禁じていますが、Boa が自分でコンパイルするので、ページの中の eval は通ります。
同じページを左右に並べます。左はあなたのブラウザが表示したもの、右はこの Worker が Wasm の中で描いた画像です。緑の枠はどちらもページの <script> が書き換えたものです。
あなたのブラウザiframe · 760×560
6 つとも緑になります — 最後の枠の 5000 万回のループも、数十ミリ秒で終わるので
疑似 Kitesurf が描いた画像PNG · 760×560
最後の枠だけ灰色のまま — Boa はループ 50 万回で JavaScript を止めます。止まる前に書いた 5 つは残ります
違いは最後の枠だけです。ページを単体で開くこともできます。
V8 と Boa が同じ isolate に同居する形になります。Worker のコードは V8 で動き、ページのコードは Wasm の中の Boa で動く。Cloudflare の Kitesurf も同じ構造です。
中身
| 役割 | 使っているもの |
| HTML のパース | html5ever |
| DOM | blitz-dom |
| CSS | Stylo — Firefox の CSS エンジン |
| レイアウト | Taffy |
| テキスト整形 | Parley |
| 描画 | blitz-paint + vello_cpu |
| JavaScript | Boa (blitz-vibey-script 経由) |
| PNG 化 | 自前。Workers に画像の API が無いので |
| フォント | Static Assets に置いて起動時に読む |
| 外向きの取得 | Worker の fetch() 1 箇所だけ |
Rust を wasm32-unknown-unknown にビルドして Worker から呼んでいます。Wasm は 15 MB ほど。
できないこと
- フォントに入れた文字しか出ません。いまは Latin と、ひらがな・カタカナ・漢字
- ページの JavaScript には実行上限があります。
while (true) はループ 50 万回で止まります。Boa には実行を中断する仕組みが無いので、上限を自分で設定しています
- 展開すると大きくなりすぎる画像は飛ばします。isolate のメモリに載らないためです
- ページの JavaScript が描画を壊したときは、JS を切って描き直します。そのときスクリプトの効果は入りません
- Web Workers と WebAssembly をページに出していません。使える機能を見て自分で「非対応」と出すサイトは、そのまま非対応の表示になります
- ページからの
fetch() は必ず失敗します。データを取ってから描くページは空のままになります
- 動くもの (アニメーション、動画、WebGL) は扱いません
- レイアウトが返ってこないページがまだあります