世界を動かす技術を、日本語で。

DOMテンプレーティングAPIの導入に最適な時期です

概要

  • Webプラットフォームに 宣言的テンプレートAPI を追加する提案
  • 現状、DOM APIは強力だが テンプレート機能が標準で不足
  • テンプレートがないことで ユーザー・開発者・プラットフォーム全体に悪影響
  • 現在は API追加の好機 であり、既存の知見も豊富
  • JavaScriptベースのテンプレートAPI導入が 現実的かつ効果的

Webプラットフォームに宣言的テンプレートAPIを追加するべき理由

  • Webプラットフォーム は最も成功したアプリケーション実行環境
  • DOM API のおかげで静的ドキュメントから動的なアプリケーションランタイムへ進化
  • DOMは強力だが、「 宣言的テンプレート」の標準APIが存在しない現状
  • データバインディング、イベントリスナー追加、プロパティ設定、XSS安全性、効率的な更新を 一貫して実現できるAPIが不在
  • これらのテンプレート機能は React、Vue、Angular、Svelte など全ての主要フレームワークの基盤
  • 宣言的テンプレートの利点
    • 命令型APIより記述性・可読性が高い
    • XSS対策が容易
    • 高パフォーマンスな差分更新
    • 型チェックや静的解析が容易
    • サーバーサイドレンダリング対応
  • テンプレート機能の欠如による影響
    • ユーザー :アプリの初回表示遅延、ライブラリのダウンロード待ち、不安定なセキュリティ
    • 開発者 :npmやCDNへの依存、学習コスト増大、ポータブルな知識の欠如、安全でないAPIの利用
    • フレームワーク開発者 :テンプレート実装の負担、性能・機能・サイズのトレードオフ
    • プラットフォーム :ネイティブ競合(Flutter、SwiftUI等)に対する競争力低下

なぜ今テンプレートAPIを追加すべきか

  • 過去にも E4Xhtmlタグリテラルなどの提案があったが、更新性が弱く失敗
  • 現在はフレームワークの進化により、 良いテンプレート構文やリアクティビティモデルの知見が蓄積
  • バニラJSやWeb Components コミュニティからも、使いやすいDOM操作・リアクティビティAPIへの強い需要
  • DOM Parts など低レベルAPIの提案も進行中だが、より高レベルな宣言的APIが必要
  • テンプレート記述の 構文・セマンティクスの共通化 が進み、標準化の好機

JavaScriptベースのテンプレートAPIの現実性

  • Tagged Template Literals (ES2015)によるテンプレート記述が既に実用化
  • React、Lit、Solid など多くのライブラリがこの方式で成功
  • JSXのような構文も人気だが、 標準化にはセマンティクス定義が必要 で課題が多い
  • 現状でも JSX→Tagged Template Literal への変換ツールが存在し、ユーザー側で選択可能
  • 将来的にJSX標準化が進めば、 テンプレートAPIをターゲットにできる下地作りが可能

HTMLベースのテンプレートAPIとの比較

  • 多くの開発者が HTMLベースのテンプレートAPI を求めている現状
  • しかしHTMLベースは バインディング構文、式言語、制御構造、更新メカニズム 等の新規設計が必要
  • JavaScriptベースなら 既存の言語機能やエコシステムを活用可能
  • HTMLベースのAPIは将来的な拡張として検討し、まずは JSベースのAPI導入が現実的

まとめ

  • 宣言的テンプレートAPI の標準化はWeb開発の生産性・安全性・パフォーマンスを大幅に向上
  • 現状のDOM API では満たせないニーズをカバー
  • フレームワークの知見 を活かし、プラットフォーム全体の競争力強化
  • まずは JavaScriptベースAPI から導入し、将来的な拡張も視野に入れるべき

Hackerたちの意見

JSXを使う代わりに、Kotlinのレシーバーやビルダーのような構文があればいいなと思ってる。これがあれば、コンポーネントの階層を表現するのにすごく便利な一般的なDSLの構文が提供できると思う。HTMLテンプレートだけじゃなくて、設定やその他の色々なことを表現するのにも広く役立つはず。テンプレートやデータバインディングの実際の意味は、そういう構文機能を使った標準関数のセットにすればいいんじゃないかな。Jetpack Composeみたいにね。

そんなに多くは要らないよ:ループ、属性の条件分岐、ノードの条件分岐があれば十分。実際、これを言語を超えて実現できるかもしれない。

ウェブにはネイティブなテンプレート、リアクティビティ、データバインディングが本当に必要だよ。何十億人ものユーザーがReactみたいなものをダウンロードして、パースして、実行するのにどれだけCPUや帯域幅が無駄になってるか想像もつかない。

でも、Reactはテンプレートじゃないよね。

TC39のシグナル提案で、その一部が進展しているよ。

もう大丈夫だよ。LLMと暗号通貨のおかげで、この無駄がちっぽけに見える。

双方向データバインディングとjsxのクローンがあれば、みんなが本当に必要とするものはそれだけだと思う。

繰り返し学んできた基本的な教訓は、APIやABIは最終的なものではないってこと。アプリケーションのニーズは、安定したAPIによって永遠に満たされることはないし、将来の問題はすべてアプリレベルの問題として考えられる。今回の提案は、プラットフォームの共通の問題がどう解決されるかの良い例だよ(Reactとか)。問題として認識されるまで上に積み上げられて、そこから下に押しやられるんだ。ポリフィルもその一例。こういう提案が成功すれば、一時的に注目を浴びるけど、その後は人々が回避しようとする古いものになってしまう。DOM APIやECMAのバージョン、古いブラウザ、システムの一部だけど触れられない技術のようにね。エントロピー、拡張、後方互換性を主要なユースケースとして考えることはできるのかな?

繰り返し学んできた基本的な教訓は、APIやABIは最終的なものではないってことだ。よくわからないけど、getElementByIdは25年間も安定してるよね。「安定したAPIなんて存在しない」って言うのは、持続可能なインターフェースを作れない人たちの言い訳だよ。これは個人的な諦めの表れであって、宇宙的な不可能性じゃない。反例はたくさんあるし、アプリケーションのニーズは他のニーズと同じように無限だよ。これらのニーズを満たすためには、新しいAPIを追加するべきで、動いているものを壊すべきじゃない。

ほとんどの有用な時間を、みんなが回避しようとしている古いものとして過ごすことになる。でもその過程で、基本的な機能がもう一段階支えられているんだ。ユーザーの要求によって新たなギャップやユースケース、盲点が常に発見されるから、漸進的なアップデートはそれだけでは価値がない。

ウェブ標準のすべての機能は、手間をかけて維持しなければならない余分なコードを意味するし、標準準拠のブラウザを作ろうとする誰もが実装しなければならない余分なコードでもある。https://servo.org/ のようなプロジェクトが、時間をかけて追いつくチャンスがあることを見たいんだ。常に拡大する範囲を追いかけるのではなくてね。ウェブプラットフォームには、ネイティブプラットフォームが持っているあらゆる機能があってほしい(もちろんプライバシーやサンドボックスの制約はあるけど)。そしてウェブ開発者の体験が素晴らしいものであってほしい。でも、これらは追加の複雑さの影響とバランスを取る必要があるよね。この場合、ネイティブテンプレーティングは本当に開発者の体験を改善するのかな?メリットがコストを上回るとは思えない。

私たちが何度も学んできた基本的な教訓は、APIやABIは最終的なものではないってこと。ウェブではそうじゃない。一度ウェブに出たものは、その形のまま永遠に依存する人がいるから。だから、20年前の決定から「スムーシュゲート」に至るAPIが今でも存在するんだよね。https://developer.chrome.com/blog/smooshgate

だからこそ、バージョンがあって古いバージョンとの後方互換性を維持してるんじゃないの?「古い」インターフェースを変えないのもそのためでしょ?

「テンプレートの良い構文がどうあるべきかは分かってる」って言うのには笑っちゃうよね。全然分かってないし。良いテンプレートは、シンボリックなものよりも視覚的なものに近いと思う。だから、昔のDreamweaverが成功したのも納得だし、多くのデザイナーがPhotoshopみたいなツールで学ぶのもそのため。これがXSLTを再現しようとしてる感じがするのも仕方ないかな。:( 誰かがうまく形成されていないものをテンプレート化したいと思うのは避けられないけど、それがうまく形成されたものに組み合わさることもあるんだよね。そうなると、どうやってやるかを探す羽目になる。ページ上の関連するエンティティがリンクされてるけど同じツリーにはない場合とかね。「label」と「for」を使った簡単な例を考えてみて。もし魔法の杖が振れるなら、私たちが必要なのは、テンプレートを標準のマークアップ文書レイアウトに合わせようとする試みを減らすことだと思う。人々は絶対位置をうまく使うことで達成できることを再現するために、無茶な努力をすることになる。確かに、物事をフィットさせるために数学を使わなきゃならないかもしれないけど、なんで同じデータで機械に何度も何度もやらせなきゃいけないのか、疑問に思うよね。

これがXSLTを再現しようとしてる感じがするのも仕方ないかな。私はXMLのファンじゃなかったけど、XSLTはエコシステムの素晴らしい特徴だったよね。今でもブラウザで広くサポートされてるし!XMLがダメなところで流行ったのは本当に残念だった—設定やIPCなど—でも、XSLTの驚くべき変換能力を持つマークアップ言語として輝くところでは衰退してしまった。XSLTが失敗したのは、実際のDSLであり、宣言的で純粋な関数型DSLだからだと思う。人々はDSLについて大きなことを語りたがるけど、結局は人気のあるホスト言語の手続き的意味を抽象化できない単純な構文の演習になってしまう。難しいタスクを簡単にするようなデザインされたDSLに直面すると…人々は学ぶ気になれないんだよね。

「テンプレーティングに良い構文がどういうものか、我々は知っている。」って聞いて、思わず笑っちゃうよね。知らないよ。この記事は、パフォーマンスやセキュリティが見栄えの良いレイヤーでは解決されないことを受け入れられていない。これは、人気の要求が常識を圧倒する時に繰り返されるウェブ技術のミスだよ。なぜなら、最下層の労働力が違いを理解できず、すべてのデザイン決定を左右するから、採用がトレーニングやメンテナンスよりも重要になるから。より良いパフォーマンスやセキュリティが欲しいなら、測定しなきゃダメで、見た目を気にして目を背けてはいけない。

テンプレートの良い構文がどうあるべきか、実はよくわからないんだよね。HTML自体が複雑すぎるし、BladeやHTMXみたいなものでさらに複雑にしようとした人もたくさんいるし。なんか、俺はHTMLよりもJSの方が好きなんだよね。JSXを使ったReactコンポーネントはいいバランスだと思う。みんながそう思うわけじゃないけど、それでいいんだ。

「テンプレートの良い構文がどうあるべきか、私たちは知っている」って言ってるのを聞くと、笑っちゃうよね。実際、全然わかってないし。良いテンプレートって、ほぼ視覚的なものだと思うんだよね、記号的なものじゃなくて。どうしてそんな結論に至ったの? あなたが言ってるのは、HTML+CSSに対する一般的な不満であって、生成方法についてじゃないように思えるんだけど。それに、なんで絶対位置について言及するの? HNでこの意見を何度も聞くけど、確かに絶対位置には必要な場面もある。でも、ページやアプリのレイアウトに使うと、ほとんどの場合、ちょっとしたコンテンツ(テキストでも!)や画面サイズの変更で絶対に崩れちゃうから、ほんとに悪夢だったよ。印刷の新聞レイアウトだってこんな風にはできないし、タイポグラフィが関わってくるからね。多分、あなたが言ってることに誤解があるのかも。でも、CSSを多く使ってた頃(今も結構やってるけど)、誰かが絶対位置を使って「ほぼ完成」ってレイアウトを作った時は、それを直すのがすごく時間の無駄だったし、フレックスやフローを使って再構築する方がいつも早かった。絶対位置をメインのレイアウトツールにすると、問題が基本的に修正不可能だったから。calc()やビューポートユニットを使う技術があるかもしれないけど、私の経験では、絶対位置は完全に静的なコンテンツやビューポートの寸法以外には適してないよ。

人々は、絶対位置を賢く使うことで達成できることを再現するために、途方もない努力をするんだよね。ウェブには、どんなデバイスのサイズや向き、能力に関わらず「ドキュメント」が見栄え良くなる必要があるから。普通のアプリ(例えば、Windowsアプリ)にはそんな要求はないし、モバイルアプリには標準化されたサイズのセットがある。ウェブだけが両方を持ってるんだよね!

「テンプレートの良い構文がどういうものか、私たちは知っています。」って言われると、思わず笑っちゃうよね。まず、ウェブプラットフォームの進歩を訴えてる人に笑うのはあんまり良くないと思う。みんなに利益があるんだから。次に、確かに今は良いテンプレート構文が何か分かってるよね。基本的にはjsxだし、Reactのファンじゃない私が言うんだから間違いない。これがウェブ全体を席巻したし、いろんなフレームワークに適応されてる。全てのjsテンプレーティングシステムが共通の属性に収束してるのは否定できないよね:テンプレートは式として、ネストによる構成、特定のテンプレート構文じゃなくて普通のJavaScriptでの制御フロー。

私たちは良いものが何かを知ってる。完璧なものが何かは分からないかもしれないけど、完璧が良いものの敵である必要はないよね。

ReactとSvelteの間には表面的な類似点しかないって言いたいな。確かに、どちらもHTMLに基づいた構文だけど、動作は全然違う。Reactは、(ほとんど)普通のJavaScript関数がマークアップの遅延表現(JSXの形で)を返す唯一の主要なフレームワークだよ。Reactにはループや条件付きレンダリングのテンプレートレベルの概念がないから、普通のJavaScriptを使うことになるんだ。

宣言型テンプレーティングがjQueryよりも実際に悪いと感じている人、他にいる?誤解しないでほしいけど、Reactをほぼ10年使ってるんだ。でも、SPAが複雑になるにつれて、DOMを命令的に制御したいと思うことが増えてきた。理由は、DOMが漏れやすい抽象化だからで、どこかのレベルでは「最後に書いたものが勝ち」っていうのが好ましいと思う。宣言型テンプレーティングがそれを扱うはずだってわかってるけど、コンポーネント間で可変状態を共有すると、すぐに崩れ始めるんだよね。

これには、Reactの人たちがDOM APIを直接呼び出すのは大罪だと思っている部分があると思う。時には、refをキャッチするのもいいし(あえて言うけど、IDでコンポーネントをクエリするのもね)、直接作業をするのも全然問題ない。実際、「速い」ライブラリや低リレンダリングのライブラリは、ほとんどそういうことをしてるよ(フォーム関連のものとか)。

Reactは好きじゃないけど、この意見には反対だな。まず、すでに宣言的DOMをオプトアウトしてinnerHTMLやrefを使うことができるし。次に、宣言的なものよりもDOMの命令的な制御でできることって、実用的じゃないことは何かある? attachShadow()やshowModal()みたいな特定のメソッドしか思いつかないけど、それでも宣言的にするのは10行のコンポーネントでできることだし。

これは、多分この分野で最も経験豊富な人が書いたことに注目する価値があるね。Googleでウェブコンポーネントのために働いていて、LitやPolymerの主要著者であり、ウェブプラットフォームの一部になった多くのコアDOM仕様に貢献している人だよ。

これを書いたのは、半端な仕様で無謀に突っ走って、解決するどころか問題を増やしてしまった人の一人だってことは覚えておくべきだね。「解決策」を押し進めるために20以上の新しいウェブ仕様が必要だって言ってるけど、ユーザー空間がすでにやってることをかろうじて実現するだけで、彼らのやってることに100%賛成じゃない人を完全に無視して、ガスライティングしてる感じ。サファリは15年前に、こういうのは宣言的な方法が必要だって主張してたんだよね。

これこそ、標準化の努力をやめて、代わりに高レベルのユーザーランドの抽象化に価値を提供する低レベルの機能に焦点を当てるべきだと思う。タグ付きテンプレート関数を作ってライブラリとして公開することに比べて、これが提供する価値は何もないよ。そのライブラリが5〜10年安定して広く使われるようになったら、初めて話す価値があるかもね。

レコードとタプルの提案が進んでいれば、JSXでレコードをボックスとして作成できたかもしれないけど、その提案は停滞してるし、特にJSXの意味論に適したレコードのアイデンティティやボックス部分が問題になってる。あの提案はただ停滞してるだけじゃなくて、撤回されてるんだ。https://github.com/tc39/proposal-record-tuple/issues/394 それはhttps://github.com/tc39/proposal-compositesに置き換えられたよ。

ここでの精神は好きだけど、まずはブラウザにもう少し低レベルのAPIを組み込むべきだと思う。みんなが標準のテンプレートシステムに合意するのはほぼ不可能だしね。でもブラウザができることは、パフォーマンスの良いネイティブな方法でDOMに差分を適用するための低レベルAPIを提供することだと思う。これがブラウザにネイティブで存在してほしいな:element.applyDiff(DocumentFragment | string, { method: 'innerHTML' | 'outerHTML' }) これなら、要素のフォーカスや入力値、オーディオやビデオプレイヤーの状態を維持しながら、属性を変異させる非破壊的な方法で差分を適用できる。IdiomorphみたいなJavaScriptライブラリもあるけど、ネイティブな解決策はもっとパフォーマンスが良くなる可能性があるよ。

記事にはDOM部分の提案がリンクされてて、これは一つの有用な低レベルAPIになるね。VDOMベースのフレームワークにはあまり合わないけど、他のフレームワークにとっては動作を簡素化し、最適化の余地を広げることができる。フレームワークなしのプロジェクトにも役立つし、特にシグナルの提案も採用されたらいいね。

「私たちはリアクティビティの領域を探求してきました。初期のDOMテンプレーティング提案には更新が含まれていませんでしたが、ユーザーランドのシステムは今やこの領域を徹底的に探求し、良いメンタルモデルや実装アプローチの良し悪しを発見しました。今、私たちは異なるアプローチからの最良の特徴を組み合わせたシステムに焦点を当てられると思います。私の知る限り、Ryan Carniato/Solid JSはまだシグナルを使って何が可能かを探求しています。この領域のユーザーランドによる探求は完全には終わっていないと思うし、さらなる革新が可能かもしれません。」