ディスカッション (11件)
WebAssembly(Wasm)を、JavaScriptと肩を並べるWebの「第一級言語(first-class language)」として確立しようという議論が盛り上がっています。これまで計算処理の高速化などの補完的な役割が強かったWasmですが、今後はWeb APIへの直接アクセスやより高度な統合が進むことで、Web開発の勢力図を根本から塗り替える存在になることが期待されています。
個人的にはまだあんまりいいアイデアとは思えないかな ;)。(最近もここで議論があったね: https://news.ycombinator.com/item?id=47295837) 。例えば、文字列のマーシャリングを2倍速くするためだけにオーバーエンジニアリングしすぎな気がするし、これはDOM APIをWASMに1対1でマッピングするっていう特定のユースケースでしか重要じゃない。他のWeb APIのほとんどは、DOMほど細切れ(granular)じゃないし文字列だらけでもない。WebGL2やWebGPU、WebAudioを主に使ってるなら、コンポーネントモデルのアプローチで2倍速くなるとは到底思えないな。JSシムで消費される時間はAPIの実装内部でかかる時間に比べれば無視できるレベルだし、コンポーネントモデルが本当に深刻な問題(WebGPUがGPUバッファをWASMヒープ外の別のArrayBufferオブジェクトにマッピングして、コピーが必要になる点とか)を解決できるとは思えない。数万件のドローコールが発生するWebGL2やWebGPUでのベンチマークを見てみたいけど、大幅なスピードアップは期待できないだろうな。
interface-typesの人たちが、WASMでのWebIDLサポートっていう当初の課題を捨てて、DOMアクセス不足を「問題なし」と宣言しながら「また別のIDL」を作り始めたりしなければ、これ全部5年前に実現できてたはず(に見える)。そうなった市場の現実は理解してるつもりだし、気まぐれや「自前主義(NIH)」だけじゃないとは思うけど、それでも失われた時間を嘆かずにはいられない。まあ、遅くても実現しないよりはマシかな。
WASMの壁(WASM cliff)はマジで存在する。ツールチェーンの複雑さとか、ゼロから何かを作り上げるまでのプロセスを考えると、使うたびに認知的なコストを払わされてる気分になる。ツールを更新しなきゃとか、最新情報を追わなきゃ、ツールをもっと理解しなきゃ…って心配になるんだよね。ここが改善されたら最高なんだけど。グルー(接着剤)なしのパフォーマンスの差はエグい。でも全然驚きはないな。WASMで面白いことをやろうとすると、ここが思いっきり落とし穴になるから、いつもみんなに警告してることの一つだ。コンポーネントで解決されるかもしれない点は(見落としてるかもしれないけど)、それによって新たな複雑さが持ち込まれないかどうかってことだ。いろんな言語での実装例を見てると、めちゃくちゃになりそうでちょっと怖くなる。まだ初期段階で標準も決まってないから、整理されてないのは仕方ないんだろうけど。Goの例(https://component-model.bytecodealliance.org/language-support/building-a-simple-component/go.html )は、ファイルを生成した後の状態がちょっと異常だよ。使う側(コンシューマー)の体験は良くなるんだろうけど、コンポーネント開発者としては、ツールや出力がもっと理解しやすいものになってほしい。しかもこれはDOMとの連携とかWeb APIのやり取りがない「ハッピーパス」での話だ。それが加わったらどれだけ複雑になるんだ? 結局、複雑さを解消してるんじゃなくて、別の場所に移動させてるだけじゃないかっていう懸念に尽きるね。
最近の新しい標準はどれも、クリーンさとか使いやすさなんて気にしてない。基本的なサンプルを動かすだけでも、JSのボイラープレートを最大限に要求してくる。どれも「エンジニア」向けに設計されていて、初心者(オーサー)に優しいデフォルトのワークフローがない。それでも、彼らがまだこの辺を気にかけてくれてるのは嬉しいよ。
Webってのは面白いよね。セキュリティ上の深刻な問題を起こさずに、誰のコードでもマシン上で動かせるようにするなんて、最初は無謀な提案に見えた。で、実際それは無謀だったわけ。主にJavaScriptのせいで、ブラウザの深刻な脆弱性に20年も耐えてきたんだから。それが無駄だったとは言わないけど、どうかしてた。そして今、ようやく正しい設計原則や対策が整って、JSエンジンのゼロデイ脆弱性が高価で珍しいものになってきたところで…それを全部引っぺがして、さらにリスクの高い新しい実行パラダイムに置き換えようとしてる。怒ってるわけじゃないよ、ある意味美しいとすら思う。
この記事は「WebAssemblyの壁」のフラストレーションを完璧に捉えてるね。パフォーマンスの高いモジュールを出荷したいだけなのに、JSのグルーコードを書いたりメンテナンスしたり、よく分からない生成ツールに頼ったりするのは、大きな後退に感じる。Dodrioの実験でJSのグルーを飛ばしてオーバーヘッドを45%削減したっていうのは、めちゃくちゃデカい。ただ、コンポーネントモデルがDOMみたいなWeb APIと直接やり取りするときの、メモリ管理の影響が気になるな。もしWasmコンポーネントがJSを完全にバイパスしてDOMを操作する場合、ガベージコレクション(GC)の境界はどう機能するんだろう? コンポーネントモデルはDOMの参照を維持するために最近追加されたWasm GCプロポーザルに依存するのか、それとも裏でJSエンジンのGCを暗黙的に動かすのか。Wasmがついに真の一級市民として扱われるようになるのを見るのが、本当に楽しみだよ。
ここで「一級市民」っていうフレーズは重要だね。ほとんどの開発者は、ピーク時のパフォーマンスが理由でプラットフォームを拒絶するんじゃなくて、摩擦(フリクション)が原因で拒絶するんだから。もし「ハッピーパス」でも依然として言語特有のグルーや生成されたシム、2つのランタイムのメンタルモデルが必要なら、WebAssemblyは「よっぽど切羽詰まったとき」にしか使われない。評価を本当に変えるのは、ベンチマークの結果が良くなることじゃなくて、「退屈な道」を簡単にすることだ。普通のツールチェーンでコンパイルして、自然にWeb APIをインポートできて、普通のWebアプリを作るのにパートタイムのバインディング・エンジニアにならなくて済む、っていう状況だよ。
WebAssemblyコンポーネントは大好きだし、これは素晴らしい進歩だ。でも、OS並みに巨大化したWeb APIを分解して、プレゼンテーションとアプリケーションを無理に混ぜないような、もっと小さくて標準的な(あるいはサブスクライブ可能な)サブセットに分割する絶好の機会をみんな逃してる気がする。例えば、情報の共有(主にテキスト)、メディアの共有、WASI 2みたいな小規模な標準インターフェース(あるいはグラフィック込み)でのアプリ共有、ネットワーク込みの複雑なアプリ共有、みたいなサブセットだ。巨大なWeb APIを小さく分割すればセキュリティ面でも有利だし、何より小規模なグループが情報共有やメディア、アプリ共有のための「ブラウザ」代替品を作るのが現実的になる。まあ、Web API(やCSSなど)が極端に巨大なことがブラウザの独占を守る主な要因の一つだから、これは進められないんだろうけど。さらに言えば、標準のWasmレジストリを作って、フルセットを実装しなくてもコンポーネントを簡単に組み合わせられるようにするとか。Wasmコンポーネントは依存関係をすべて追跡するのかな? DOMみたいな巨大なモノリシックAPIが利用可能であることを前提にするんだろうか? 君たちがやってるのは、本質的に分散型オペレーティングシステムの定義を作ることなんだ(Webが本質的にそうであるように)。自分たちで巨大なAPIを実装しなくてもクライアントを作れるように、設計できるはずだ。
最新のWebAssemblyを知りたいなら、コンポーネントモデルの本をチェックしてみて。https://component-model.bytecodealliance.org/ WebAssemblyの本当に強力な部分を紹介するハイレベルなコンセプトや実践的なコードサンプルとかが載ってる。特にJSエコシステムに関しては、知っておくべきプロジェクトが3つある。https://github.com/bytecodealliance/StarlingMonkey 、https://github.com/bytecodealliance/ComponentizeJS 、https://github.com/bytecodealliance/jco 。今のところ一番成熟してるツールチェーンはRustだけど、LLVMベース(clang経由のC/C++)なら大抵のものはサポートされてる。GoやPython、他の言語のサポートもどんどん良くなってきてるし(tinygoやbig goとか)、これからもっと増える予定だ。WebAssemblyの目標の一つは、ローカルのツールチェーンにコンパイルターゲットとしてすんなり溶け込むこと。毎週そこに近づいているよ。
このブログ記事は、問題の根源を象徴してる気がする。つまり、核心となる問題(DOMへの直接アクセスや、JSだけが持ってる特権的なアクセス権限)を避けて通ってるんだよね。