もっと知られて欲しい、インタラクティブなWebアプリケーションを作るReact、Vueではない選択肢
最近Phoenix LiveViewや、それにインスパイアされた技術に注目しています。ReactやVueのようなものとインタラクティブなWebアプリケーションを作るという目的は一緒ですが、もう少しサーバサイドに軸足を置いた技術です。
これらの面白さ、有用性の割にあまり知られていないように思いこの記事を書いてみました。
誰向けか
作るアプリケーションの特性や開発組織によって適した技術は違うと思います。
以下で紹介する技術は特に、
であればかなり良い選択肢になるんじゃないかと思います。
Turbolinksのようなものを敢えて選択していた人だったり、SPAを書いてみて「できるものの割に開発コストがかかりすぎじゃないか?」と感じたことがある人が触ってみると、きっとかなり面白いと感じると思います。
一体どんなものか
端的に言えばReactやVueのコンポーネントをサーバサイドに持っていったようなものです。
ブラウザ上で
- イベント発火
- 状態更新
- 状態からDOMツリーの理想的な状態を計算
- DOMツリーの更新
していたうち、2, 3の部分をサーバにもっていき、サーバ、クライアント間のやりとりはライブラリが面倒をみてくれます。やりとりに関してはWebSocketを使う/使わないなどライブラリによって異なります。
これの一体何が嬉しいのでしょう?
メリット
開発速度
サーバサイドにしかない情報を使いたい時の手数が結構変わってきます。
クライアントとサーバ間のインターフェースをライブラリが決めてくれているおかげで、自分で管理しなけばいけない部分がかなり減ります。
例えば以下のようなことが必要になっていた場面でも、
- どんなエンドポイントでどんなフォーマットで情報をやりとりするか考える
- Web APIのエンドポイント作成
- Web APIクライアント作成/生成
- JSでグルーコードを書く
LiveViewの例であれば
- HTML要素に特別なattributeを追加する
-
<button phx-click="like">like/button>
でclick
されたらlike
イベントがサーバに送られる
-
- サーバサイドのコードとしてイベントハンドラを書く
-
handle_event("like", _, socket)
といった関数を定義して状態を更新する
-
とかなり単純化されます。この楽さはコードを見たり書いたりしないとなかなか伝わりづらいかもしれません。
また、サーバサイドに充実したviewヘルパーがあるのであれば、それがそのまま使えます。Railsでの充実したヘルパーに慣れていると、Reactなどを書いたときにもどかしく感じたことがある人もいるのではないでしょうか。
デフォルトでSSR
言語選択の自由
個人的にはJSはコレクション操作や日時操作周りで不便に感じてnpmモジュールを追加したりすることが結構あったりしますが、標準ライブラリが充実している言語で書けば依存ライブラリを増やさなくてよくなります。
またElixirだと、パターンマッチ便利だなーと思う場面がちょいちょいあります。
エラーが起きる環境が限定される
@sentry/browserのようなものでクライアントサイドでエラー収集をすると以下のようなノイズの多さに辛さを感じることがあります。
- 同一のエラーでもブラウザによってエラーメッセージが違って分散する
- 広告が起こすエラー
- 拡張機能が起こすエラー
- ネットワークの問題によるエラー
- かなり古いブラウザでしか起きないエラー
- etc.
自分で書いたコードの、より多くの部分がサーバサイドで動くのでノイズに煩わされづらくなります。
JSのバンドルサイズが小さくなる
LiveViewのバンドルサイズであれば、少し古いですがPhoenix LiveView: Interactive, Real-Time Apps. No Need to Write JavaScript.によると
Name | minified size |
---|---|
LiveView.js + morphdom | 29KB |
Vue 2.5.20 | 88KB |
React 16.6.3 + React DOM | 112KB |
Ember 3.0.0.beta.2 | 468KB |
実際のアプリケーションではクライアントのコードやnpmモジュールが追加されて、更に違うと思います。
デメリット
もちろん銀の弾丸ではなくデメリットもありあます。
オフラインでは使えない
WebSocketを使わないものであれば、Service Workerで一応動くようにはできると思います。
光遅すぎ問題の影響を受ける
操作から反応までの許容レイテンシーが厳しいものには適していないと思います。エディタ、アクションゲームのようなもの。そういう部分だけJSで書くのは全然可能です。
サーバサイドの使用計算リソース増
状態管理をする必要がありますし、テンプレートのレンダリング回数も増えます。
運用で考慮しなければいけないことが増える場合がある
特に新たにWebSocketを使う場合であればコネクション数やコネクションあたりのメモリ使用量の監視、ロードバランス、デプロイ戦略 etc.
分業がしづらくなる
フロントエンドエンジニア、バックエンドエンジニアと明確に役割が分かれていたり、細かく分業している大規模なチームには向いていないと思います。
各言語での実装
以下のようなものがあります。
- Elixir
- Ruby
- StimulusReflex
- おそらくTurbolinks 6も似たようなものになりそう(ただし2020年内に出るか出ないかという感じ)
- PHP
- Python
実際に使われている例の動画
TwitterクローンRTAバトルの様子です。
最後に
以上紹介でした。
個人的にはメモリ使用量の小ささと監視しやすさ、OTPとの相性や書いていての楽しさでPhoenix LiveViewを主に触っています。実際少し書いてみた印象だと、Railsに初めて触れた時のような「おぉ」感があります。
より詳しく知りたい場合の導入には、
ElixirConf 2018でのPhoenix.LiveView紹介トーク
がオススメです。
Discussion