今回は、Rails7でデフォルトとなったHotwireとはどういう機能なのか。そして、現在主流であるReactやVue.jsのようなSPAと比較してどんなメリットがあるのかといった点について、学校の掲示板の例えを交えながら紹介します。
前提知識
Hotwireの概要
Hotwireとは、モダンなWebアプリを作るためのアプローチであり、Html Over The WIRE の略称です。従来のバックエンド(サーバ)に処理を集中させる方式から、フロントエンド(クライアント)にも処理を分散させることで、ページ遷移の高速化といったUIの向上を図る目的があります。
Hotwireは大きく分けて次の3つのライブラリで構成されます。
Turbo ←本記事で取り扱います
Stimulus(JavaScriptを記述する際にレールの役割を担います)
Strada(モバイル開発で使います)
そして、Turboはさらに次の4つの要素で構成されます。
Turbo Drive
通常のページ遷移をJavaScriptのfetchを用いた非同期リクエストに置換する機能です。そして、取得したHTMLの<head>タグの内容を解析し、更新が必要な場合は新しいCSSやJavaScriptを適用させ、不要な場合はそのままにすることで無駄な処理を減らします。また、新しい<body>タグの内容に置換することによってリロードせずにページを更新することができます。
Turbo Frames
大枠は先述の Turbo Drive と同じですが、<body>タグではなく、<turbo-frame>タグの内容を新しいものに置換することで、より部分的な更新を実現できる機能です。
Turbo Streams
先述の Turbo Frames の機能を拡張したものと考えてください。複数箇所の同時更新や、要素を置換するだけでなく追加や削除もすることができる機能です。
Turbo Native
サーバ・クライアントの通信方式
通常の同期通信(MPA)
ユーザーがリンクをクリックするなどして、クライアントはサーバに指定されたページをリクエストします。このリクエストに対して、サーバはページを生成し、クライアントにHTMLをレスポンスします。このとき、新しいページが返されるまでクライアントは待機状態となり、レスポンスを受け取った後、前のページは新しいページにすべて置き換えられます。このような方式をMulti Page Application(MPA)と呼びます。
この仕組みを学校の掲示板に例えると、まず、掲示板の管理者(クライアント)が掲示物の作成者(サーバ)に掲示板の更新を依頼します。すると、作成者は更新の有無に関わらず掲示物を一度すべて取り外します。そして、作成者は情報の更新が必要であれば新しい掲示物を作成し、更新が不要であれば全く同じ掲示物を作成します。その後、新しくなった掲示物を再度掲示することで掲示板の更新が完了します。
しかし、「わざわざ掲示物すべてを取り替えなくても、更新する掲示物だけを取り替えればもっと簡単に済むのではないか」と考えるのは自然なことです。この考えを実現するのが、次に紹介する非同期通信です。
SPAを使った非同期通信
まず、ページを初めて読み込む際に、必要なデータを一括で取得します。そして、変更させたい箇所のデータをJSON形式でサーバから取得し、クライアント側でHTMLを作成することで部分的に更新させることができます。このような方式を Single Page Application(SPA)と呼びます。なお、この説明からわかる通り、本形式は1つのHTMLをベースとして、内容の更新等はJavaScriptが担うためにSingleを冠しています。
この仕組みをMPAとの違いを意識しながら学校の掲示板で例えると、最初に管理者が作成者に掲示板の更新を依頼する点は同じですが、作成者はあくまでも変更内容を管理者に伝えるだけであって、作成者が新しく掲示物を作り直すことはしません。そのため、管理者自身が変更内容をもとに掲示物を作成し、古いものと取り替えることで更新が完了します。
ここで疑問なのは、なぜ掲示物を作成者ではなく管理者が作るのかという点です。もし、掲示物の更新が1日に何回も必要な場合、作成者がその都度掲示物を作って届けるよりも、作成者に内容だけ伝えてもらい、管理者自身が掲示物を作り変えてしまった方がより迅速に対応することができるのです。ただ、これはあくまでも例えであって、実際にプログラムする際は、サーバ側の処理とクライアント側の処理の双方を意識しなければならないという問題が発生します。この問題を解決したのが次に紹介する Turbo です。
Hotwire(Turbo)を使った非同期通信
仕組みとしてはSPAと似ている部分もありますが、サーバからJSONではなくHTMLを取得して、部分的な更新を実現します。つまり、クライアントとサーバとの間に関与することで、HTMLをベースとしたSPA風な非同期通信を実現しています。
この仕組みをSPAとの違いを意識しながら学校の掲示板で例えると、管理者が作成者に依頼する点は同じですが、変更する掲示物を作成者が作り直して届けるという点に違いがあります。つまり、最初で述べた「わざわざ掲示物すべてを取り替えなくても、更新する掲示物だけを取り替えればもっと簡単に済むのではないか」という問いに完璧に対応しているのがこの方式となります。
Hotwire vs. SPA
それでは、ReactやVue.jsを代表とするSPAと、Railsのデフォルト機能であるHotwireを比較し、それぞれのメリットについて説明していきます。
まず、両者に共通するメリットとして、高速でスムーズな操作感を実現できるという点が挙げられます。どちらも変更が必要な箇所だけを非同期で部分的に更新するため、ページ全体をリロードする必要がなく、無駄な通信を抑えつつ効率的な操作が可能です。また、SNSのようなリアルタイム更新にも対応できるため、UIが向上します。
次に、SPAのメリットとしては、オフライン対応がしやすい点があります。SPAは初回の読み込み時に必要な情報を一括で取得するため、通信が制限された状態でもキャッシュを活用してある程度の操作が可能です。また、コンポーネント単位で要素を管理するため、コードの保守性や再利用性が高くなります。これにより、開発者は各コンポーネントを個別に修正・再利用しやすく、開発効率を向上できます。
一方、Hotwireのメリットとして、導入コストが低い点があります。Hotwireは、HTMLの送受を中心に構築されるため、複雑なフロントエンド処理を避け、サーバーサイドの開発に集中しやすくなります。さらに、JavaScriptの記述もほとんど必要ないため、Railsのコードだけで開発が進めやすいのもメリットです。
それでは逆にデメリットはどういった点でしょうか。SPAのデメリットとして、ページがクライアントサイドで生成されるためSEOへの対応が難しい点が挙げられます。これは、検索エンジンがページ内容を読み取れないケースがあるためです。しかし、現在はSSRやプリレンダリングの導入によって、この問題はある程度改善されています。また、SPAはJavaScriptに依存するため、古いブラウザやセキュリティ設定によってはページが正しく表示されない可能性もあります。
Hotwireのデメリットとしては、サーバーサイドに重点を置いた方式であるため、JavaScriptを使って徹底的にUIを向上させるには限界がある点が挙げられます。また、ReactやVueなどと比べて日本語の資料が少ないため、情報が限られており、学習コストが高くなることもデメリットです。
まとめ
特徴 | Hotwire | SPA |
---|---|---|
例 | Turbo、Stimulus | React、Vue.js |
HTML生成 | サーバで生成 | JSONを元にクライアントで生成 |
操作性 | 高速 | 超高速 |
開発性 | シンプル | 複雑だが、再利用性は高い |
リアルタイム更新 | Turbo Streamで対応可 | 対応可能 |
オフライン対応 | 難しい | 簡単 |
導入コスト | 低い | 高い |
日本語資料 | 少ない | 多い |