- Htmxの基本的でシンプルなアイデアは本当に気に入っているが、チーム全体で使ってみた結果、実際には単純ではなくかなり複雑だと分かった
Htmxの属性継承は明らかな失敗
- コード断片における属性継承は暗黙的で、意外性がある
- CSSのように、継承は安価なハックだが代償を伴う
- 著者の「行動の局所性」という主張と矛盾している
- 複数の属性でデフォルト継承の挙動が異なる(例:
hx-delete は継承されないが、hx-confirm と hx-ext は継承される)
- 例外を覚えなければならず、結局すべてを明示的に書くことになって継承が無意味になる
たいていの興味深いWebアプリはDOM要素を丸ごと置き換えられない
- DOM要素はほとんど常にブラウザローカルな状態を持つ(例:
<details> 要素の開閉状態、<input> 要素の入力値、ドロップダウン要素の開閉状態)
- Htmxが
outerHTML をそのまま置き換える単純な方式を使うと、こうした状態はすべて失われる
- Morphdom拡張でも予想に反して一部の要素が上書きされる
DOM要素そのものに状態を保存するのは悪い考え
- Morphdomは前項の苦しさを解決するためのものだが、Htmxの動作方式は要素を丸ごと置き換えることを前提にしていることが分かった
- リクエストキューをDOM要素そのものに保存している
- リクエストを開始すると、その要素またはそれを参照する別の要素にリクエストキューが生じる
- DOM要素を丸ごと置き換えるとキューがリセットされるため、いくつかの悪い失敗モードを避けられる
- しかしMorphdomでは要素が保持されるため、キューも保持される
- Htmxの設計前提が破られる、いわば未定義動作の領域に入ってしまう
デフォルトのキューイングモードはひどい
- デフォルトでは、Htmxは同じキュー(要素)から別のリクエストがトリガーされると進行中のリクエストをキャンセルする
- これがデフォルト戦略になっている
- この事実に後から気づいた
- とても直感的とは言えず、作業が失われることを意味する
イベントトリガーは局所的ではない
- イベントトリガーは何かを起こす助けになることが多いが、局所的でない効果であり、属性継承と似た問題がある
- サーバーサイド言語でDSL的な仕組みを使えばある程度助けになるが、古いJavaScriptのコールバック中心プログラミングに近い感覚がある
- イベントが発生したら、それを「購読」して何かを行う
コンポーネント状態をうまく保てない
- DOM要素の状態問題に似た、より広い問題として、自前のコンポーネントにも独自の状態がある
- たとえば、サーバーに必要な独自状態(例: 結果セットのページ)と、ReactやWebComponentsに必要な状態を持つ3つのセクションで構成されたページが欲しい場合、親コンポーネントと子コンポーネントの間で状態を同期する問題がある
- Htmxはこれに対する良い方法を提供していない
- クエリパラメータ、隠しフォーム入力、イベントトリガーなどを使う案はあるが、どれにも大きな注意点がある
- ReactとHalogenはこれに対する答えを持っている
- どちらの場合も、子コンポーネントは独自の状態を持ち、親は「助言」のような
props を提供できる
- さらに子は独自の内部状態も持ち、
props を無視したり優先したりできる
props は一般にサーバーから提供されるかサーバー由来であり、状態は一般にクライアントサイド状態である
- Reactで提供される既製コンポーネントや使わざるを得ないコンポーネントでは、Reactが必要なことが多い
- ReactとHtmxはうまく相互作用しない
- WebComponentsでも満足のいく作業はしたが、それらには驚くほど奇妙な制約がある
- サーバーサイド言語から使うReactコンポーネントに直接ブリッジを作ったこともあるが、一般にHtmxとReactは状態フローとDOM要素管理を巡って衝突する
- Alpineも試したが良かった。ただしこれは別のクライアントサイドプログラミングライブラリなので、コードベースにすでにReactがあるなら重複になる
それでも利点はある
- サーバーサイド言語を使えることは、非常に明白で議論の余地のない利点だ
- チーム内の誰も、このビジネスロジックをすべてTypeScriptで書き直したいとは思わないだろう
- DBの型からフロントエンドの型へのシリアライズが不要になる
- サーバーサイド言語のより強力な抽象化機能を使える
- 同じバリデーションのためにフロントエンドとバックエンドの両方を実装する代わりに、サーバーサイド言語のフォームビルダーを使える
- ただし、上記の欠点も事実である
Htmx-in-React?
- 魅力的な将来の方向性として、React上でHtmxを再実装することが考えられる
- サーバーがJSONの塊を送れば、Reactがそれを仮想DOMコンポーネントに変換する
- そうなればコンポーネント状態の問題は解決されるだろう
- Reactコンポーネントを使うための特別なブリッジも不要になるだろう
- React対応のWebフェッチライブラリを使え、Htmxで問題となるある種のキューイング選択も注意深く避けられる
- Morphdomの問題やブラウザDOMの入力要素の問題も解決されるはずで、これはReactではほぼ解決済みの問題だ
- このやり方ならHtmx依存を取り除きつつ、アイデアの利点は維持できる。ただし、そのような大きな取り組みを始められるだけの予算が与えられる必要はある
GN⁺の意見
- Htmxの基本アイデアは魅力的だが、実運用ではさまざまな複雑な問題に直面しうる
- 属性継承、DOM要素の置き換え、キューイングモードなど、Htmxの一部の設計は直感的でなく予期しない動作を引き起こしうる
- ReactやWebComponentsとの統合も容易ではないようだ
- それでもサーバーサイド言語を使えることは大きな利点だ
- 今後、ReactベースでHtmxを再実装するのも興味深い方向になりうる
12件のコメント
無関心より関心を持たれるほうがいいですよね〜。私はHTMXが好きです。思想も含めて。
SQLiteともかなり通じるものがありますね(笑)
SQLiteとHTMXはどのような点で似ているのでしょうか?
SQLiteに似てる?
コメントが深いですね。哲学とは..
SPAが登場する前にサーバーサイドレンダリングとjQueryでWeb開発をした経験があれば、そちら系の技術だとすぐに理解できると思います。おそらくSPAでWeb開発に入門した方々が、新しいものを追い求める中で勘違いしているのだと思います。
この記事は韓国で書かれた文章ではないように思うのですが。
そうですね。シンプルなページのために作られたツールのように思えるのに、妙な例やユースケースを持ち出して、それに向いていないなどという議論がなぜ起こるのか分かりません。
htmx のメインページから分かるように、htmx は(それだけで完結するなら)React を含むモダンなフロントエンド技術は不要だという立場に近いです
それは、htmx が注目される理由に関係しています。この記事も海外の寄稿文を翻訳したものですが、海外では React のさまざまな状態管理にうんざりしているのです。そこで、React と似た機能を提供しつつ、React と違って状態管理を必要としない htmx が、React の代替として見られました。だからこそ、htmx は引き続き React と比較されているのです。
うーん。その理由なら、React を置き換えられると主張しているものを持ってきて比較するのが適切なのではないでしょうか?
このページに列挙されている特徴を見るだけでも、HTMX は複雑なページに入れられるようなものではなく、React をまったく置き換えられるような何かでもないと思います。
Hacker Newsの意見
属性継承については意見が分かれている。
htmx.config.disableInheritanceオプションで無効化できるフロントエンドに飛び込まなかった理由は、選択肢が多く批判も多いうえ、技術トレンドが頻繁に変わるからである
HTMX を使って高性能なストアフロントを構築しており、結果には満足している
"HTMX in React" というアイデアは、React Server Components を再発明したようなものだ
デフォルトの待機モードが不合理だという意見には同意しない
HTMX を初めて使ってみたが、簡単な作業には手軽に適用できて面白かった
状態に対する不満を読んで、作者は React 以前に Web サイトを作ったことがないのではと思った
HTMX に Turbo Mount のような機能があるのか気になる
morphdom が予期せず一部の要素を上書きしてしまう問題について、もっと知りたい