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

コードベースからReact.jsを削除し、UIインタラクティビティのためにHtmxを適応する (2023)

概要

Misagoは現在、DjangoテンプレートとReact.jsコンポーネントの二重実装による課題を抱えている。 HTMLカスタマイズが困難で、パフォーマンスや開発効率に悪影響が生じている。 HTMXの導入でサーバーサイドレンダリング中心のシンプルな構成へ移行を検討中。 React.js依存の脱却は段階的に進める予定。 移行によりJSサイズ削減や保守性向上が期待される。

Misagoの現状と課題

  • 現在のMisago は、Djangoビューでスレッド一覧データを取得し、ほぼ完成したHTMLをテンプレートで出力、その中に同じデータのJSONも埋め込む構成
  • JavaScript がロードされると、ページ内のJSONを読み取り、Djangoテンプレートで描画されたHTMLをReact.jsコンポーネントによるHTMLで置換
  • ボタンの有効化 やUIのタイムスタンプ更新など、インタラクティブな機能がJS起動後に有効化
  • 二重実装の問題
    • DjangoテンプレートとReact.jsコンポーネントの両方で同じページを実装する必要
    • HTMLカスタマイズ時、Djangoテンプレートのみ編集すると、React.jsのHTMLに上書きされてしまい、意図した変更が反映されない混乱
    • ゲスト・ユーザー両方がアクセスするビューは、DjangoとReact.jsの双方で実装必須
    • APIとJSONシリアライザの実装・メンテ負荷
    • JSONシリアライズ処理によるレスポンス生成の遅延
    • 翻訳メッセージがdjango.poとdjangojs.poの両方に分散し、管理が煩雑
    • JavaScriptの初期ダウンロードサイズ増大
    • 古い・低スペック端末でのパフォーマンス悪化
    • プラグイン開発時もDjangoテンプレートとReact.js双方の知識が必要
    • サイトビルド時にJavaScriptビルドステップが必須

検討中の解決策

  • Djangoビューとテンプレートの最小化、SEO用にのみ残し、UIは全てReact.jsアプリ化しAPI中心運用
  • DjangoをAPIのみに縮小 し、Next.jsやRemix.run等のJavaScriptフレームワークによるサーバーサイドレンダリング活用

サーバーサイドレンダリング回帰の価値

  • 多くのフォーラムソフトウェアは従来通りサーバーでHTMLを生成し、必要な箇所のみJavaScriptでインタラクティブ性を付与
  • この方法では、前述の二重実装やパフォーマンスの問題が発生しない
  • フォーラムのインタラクティブ性は、モデレーションやスレッド監視、返信、通知、投票などページの一部に限定されている
  • これらはReact.jsが登場する以前から、フルリロード無しで実現されていた

HTMX導入案

  • HTMX は、HTMLの一部を「動的アイランド」として定義し、ユーザー操作時にサーバーから新しいHTMLを取得して該当部分のみ差し替える小型ライブラリ
  • 例)スレッド一覧を大きなアイランドとして、カテゴリ変更時にその部分だけ新しいHTMLに置換
  • Django側はHTMXリクエスト時のみ該当アイランド部分のHTMLを返却
  • JSONシリアライズや専用のJavaScript/React.js記述が不要
  • HTMXは宣言的なjQueryの$.get("url", "#outlet")や、RailsのTurbolinks的な役割
  • シンプルな構成・保守性向上

管理画面(Admin Panel)について

  • 管理画面はSPA化せず、 従来のDjangoビュー を活用
    • 再利用可能なDjangoビュー群で90%の作業を自動化
    • ページ追加はベースビュー選択・フォーム定義・基本テンプレート作成で完結
    • SPA化による複雑化を回避

HTMX移行計画

  • React.jsからHTMXへの移行は 段階的 に実施
    • 例)Navbar → スレッド一覧 → スレッドページ → ユーザープロフィールの順で移行
  • ただし、プラグイン・権限・新パーサーの実装が先行課題
  • HTMX移行は2024年後半以降を予定
  • Bootstrap最新版への移行も同時に検討中

JavaScriptサイズの現状と削減目標

  • Misago 0.39のJSサイズ
    • vendor.js: 679kb(214kb gzipped)
    • misago.js: 615kb(124kb gzipped)
    • django-i18n.js: 102kb(25.4kb gzipped)
    • 遅延ロード: hljs.js 144kb(49kb gzipped)、zxcvbn.js 820kb(430kb gzipped)
  • React.js等の依存削減により、これらのサイズを大幅に削減予定

HTMX移行中の一時的な挙動

  • 移行期間中は、 React.jsもHTMXも未導入 な部分が「マルチページアプリケーション」化
    • 例)ユーザーオプションページでリンクやフォーム送信時にフルリロード発生
    • ただし、投票や「いいね」などフルリロードが不快な箇所には暫定AJAXやHTMXを適用

直近の改善事例

  • 「Forum options」ページを「Account settings」ページに刷新
    • Djangoビュー+一部HTMXで実装
    • JSサイズ:misago.jsが578kb(107kb gzipped)に削減(旧比37kb/17kb減)
  • スレッド一覧をDjangoビュー+HTMXで再実装
    • JSサイズ:misago.jsが530kb(99kb gzipped)に削減(旧比48kb/8kb減)

Hackerたちの意見

これやってくれて嬉しい!htmxはサーバーレンダリングにぴったりだし、ほとんどの場合はそれが正しい選択だと思う。テンプレートの中にちょっとしたVueJSやReactJSのアプリを入れれば、かなりカスタマイズされたインタラクティブ性も実現できるしね。

ReactJSやVueJSをちょっとしたインタラクティブ性のために使うのは、あまり正しいアプローチじゃないよね。「ちょっと」使うために持ち込むのは意味がない。Reactやそれに似たフレームワーク(Angular v2、Vue.js)が安定したのは、適切な抽象化があって、動的なHTMLを管理するための他の要素がほぼ同じ方向に収束するからなんだ。

それって基本的に大きなハックだよね。実際のアプリでは、htmxを使うとフロントエンドにJSを入れなきゃいけなくて、結局はハックでまとめることになる。15年前にPHPとJSを使ったのと同じようにね。

何年も前から言ってるんだけど、全ての建物は駐車場にすべきだと思う。だって、テナントが必要なら駐車場の中にミニ住宅を入れればいいし、オフィスが必要なら駐車場にミニオフィスを置けばいい。完璧じゃん!駐車場の建設はすごくシンプルでクリーンだし、他の建物は複雑すぎる!これからは駐車場だけを建てるつもり。 (でも、駐車場のない住宅の逆の例もあるよね!住むには最高だけど、物を置く場所も車を停める場所もない!)

HTMXはフォーラムソフトウェアにぴったりだと思う。フォーラムサイトは主にテキストや音声、動画、画像コンテンツの形で非インタラクティブなコンテンツを提供するから、これらは全部HTMLとCSSで表現できる。HTMXを使えば部分的なレンダリングやサーバーからのイベントでライブ更新ができる。これでユーザーのアクションに基づいて動的に読み込まれる「クライアントサイド」の感覚にかなり近づけるよね。フォーラムで思いつく唯一の本格的なダイナミックなSPAのような機能はWYSIWYGエディタだけど、これはウェブコンポーネントとして作れる。柔軟なハイライトや引用システムは、純粋なHTMXではちょっと難しいかも(Mediumのコメント機能みたいに)。だから、クライアントサイドのJSでいくつかのものを作る必要があるけど、メインの体験はHTMXで十分作れると思う。

フォーラムで思いつく唯一の本格的なダイナミックなSPAのような機能はWYSIWYGエディタだけど、これはウェブコンポーネントとして作れる。柔軟なハイライトや引用システムは、純粋なHTMXではちょっと難しいかも(Mediumのコメント機能みたいに)。だから、クライアントサイドのJSでいくつかのものを作る必要があるけど、メインの体験はHTMXで十分作れると思う。インタラクティブ性はずっとそうやって機能してきた。サーバーサイドで全部レンダリングして、上にJSでインタラクティブ性を追加する。ほとんどのウェブ開発者は、ReactやVueなどが特定の問題を解決するためのものであることを忘れてしまった気がする。これは非常に狭くて特定の問題で、ページ間の移動がフルページリロードを引き起こさないことなんだ。でも、ウェブはSPAsが必要だった頃から大きく変わった。1. 平均的なデバイスと接続が10〜15年前よりも信じられないほど速くなった。コンテンツの受信とレンダリングは、2G接続や限られたハードウェアのモバイルデバイスの時代ほどの問題じゃなくなった。数年前の非常に低価格の電話でも、今では数百KBのHTMLやJSを読み込むのに全く問題がない。2. ウェブ技術はあらゆるレベルで進化した。サーバー技術、クラウド技術、ブラウザ技術。Reactやその仲間たちは、現代のウェブにはほとんど関係のない問題を解決している。要するに、今日では完全にサーバーサイドでレンダリングされたアプリケーションでも、アプリのような、SPAのような体験ができる。クライアントに送るコードもずっと少なくて済むしね。オフライン機能を大いに活用し、インターネットが利用可能でなくても動作し続けたいウェブサイトやアプリケーションはごくわずかで、これらのレンダリングライブラリに苦しむことはない。私はその概念や線形について話している。でも、それ以外のものでは、Reactのクソみたいなものを使うのはユーザーにとって良くない。何十億ドルの企業がleetcodeの忍者を雇っても、これらのライブラリからは受け入れられるユーザー体験やパフォーマンスを引き出せないのは偶然じゃない。彼らは間違った問題に間違ったツールを強制している。彼らは2018年に生き続けていて、結局のところ、ReactやAngular+Tailwindのクソの唯一の言い訳は、他に何も知らない開発者の世代がいて、適切なツールを見つけるための技術的スキルを長い間失ってしまったからだ(もしそれがあるなら)。これは慣れの問題であって、技術的な決定が正しいわけじゃない。「oracle/mysql/ibmなら間違いない」と言われるけど、実際には間違えることができるし、それが現れている。さらに悪いことに、2026年にはLLMを使ってさまざまな解決策やアプローチを試すのが信じられないほど安くなっているのに、人々は同じようなモンスターを使い続けている。

フォーラムサイトは主に非インタラクティブなコンテンツを提供してると思うけど、「エンドレススクロール」は、まあインタラクティブではないけど、そういうものと仲良くできる「ただのHTMLドキュメント」ページのメタファーを壊す良い例だね。個人的には、エンドレススクロールを実現するために必要なUIの妥協が嫌いなんだけど(ctrl-Fやページ内容のエクスポートができないとか)。でも他の人は明らかにそれを好んでるよね。HTMXみたいなプラットフォームに移行する際に、そういうことを諦めることになるのかな?

すごく同意する。これを「フォーム、ビュー、フィルター、ページネーションを中心にしたウェブアプリ」にまで広げたいね(はい、私は年寄りです)。ここで話されているトピックに関連するhtmxの部分は、数年前に劣ったクローンを作ったことがあるよ。それは「アイソモーフィック」で、私たちのPHPベースのCMSに合わせて作られていて、フィルター、検索フォーム、ページネーションを扱えたんだ。フォーラムには確実に適してるし、今も市場にあるPHPベースのフォーラムソフトウェアのベンダーは同じパラダイムに従ってるね。

言い換えると、「HTMXは、_APP_になりたい数人を除いては、すごく合ってると思う」って感じかな… :)

基本的に、私はすべてのWebアプリにHTMXを使ってるよ。PWAも含めて、iOSやAndroidでネイティブアプリに近い形で動くやつね。最高だよ!DaisyUIとTailwindCSSも組み合わせて使ってる。普通のHTMLで部分的に書いて、HTMXがブラウザにSPAのようなインタラクティブ性を追加してくれるのがすごく楽しいんだ。

ユーザーのスマホのホーム画面にショートカットを作れるのは知ってるけど、その設定だと何回もタップすると複数のタブが開いちゃう問題に遭遇したことがあるんだ。何かいい回避策見つけた?

HTMXを使ったPWAはオフラインでどう機能するの?「新しいマークアップフラグメントをサーバーから取得する」アプローチはここでは捨てなきゃいけない気がするけど、オンラインアプリには簡素化が必要だよね。

Hacker Newsで議論の続きを見る