もっと知られて欲しい、インタラクティブなWebアプリケーションを作るReact、Vueではない選択肢

2020/10/06に公開

最近Phoenix LiveViewや、それにインスパイアされた技術に注目しています。ReactやVueのようなものとインタラクティブなWebアプリケーションを作るという目的は一緒ですが、もう少しサーバサイドに軸足を置いた技術です。

これらの面白さ、有用性の割にあまり知られていないように思いこの記事を書いてみました。

誰向けか

作るアプリケーションの特性や開発組織によって適した技術は違うと思います。

以下で紹介する技術は特に、

  • webがメイン
  • 個人開発だったりフルスタックエンジニア少数からなるチーム
  • UIの複雑度がめちゃめちゃくちゃ高いわけではない

であればかなり良い選択肢になるんじゃないかと思います。

Turbolinksのようなものを敢えて選択していた人だったり、SPAを書いてみて「できるものの割に開発コストがかかりすぎじゃないか?」と感じたことがある人が触ってみると、きっとかなり面白いと感じると思います。

一体どんなものか

端的に言えばReactやVueのコンポーネントをサーバサイドに持っていったようなものです。

ブラウザ上で

  1. イベント発火
  2. 状態更新
  3. 状態からDOMツリーの理想的な状態を計算
  4. 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.

分業がしづらくなる

フロントエンドエンジニア、バックエンドエンジニアと明確に役割が分かれていたり、細かく分業している大規模なチームには向いていないと思います。

各言語での実装

以下のようなものがあります。

実際に使われている例の動画

TwitterクローンRTAバトルの様子です。

最後に

以上紹介でした。

個人的にはメモリ使用量の小ささと監視しやすさ、OTPとの相性や書いていての楽しさでPhoenix LiveViewを主に触っています。実際少し書いてみた印象だと、Railsに初めて触れた時のような「おぉ」感があります。

より詳しく知りたい場合の導入には、
ElixirConf 2018でのPhoenix.LiveView紹介トーク
がオススメです。

Discussion