Ruby on RailsのMPAでForem流の"Islands Architecture"を導入するメリット・デメリット
Forem流のIslands Architectureとは
Forem(dev.toのOSS)はメインの技術スタックは現在でもRuby on Railsであり、
フロントエンドにはPreactとその他いくつかのフロントエンドのスタックを使って実装されています。
CDNをつかって積極的にキャッシングされているということもあり、サイトの応答速度は
いっとき「阿部寛のホームページくらい早い」ということが言われただけあり、レスポンス速度には定評があります。現在でもHerokuで運用されていますが、まだ早く表示されるので、よかったらご覧ください。
そんな一世を風靡したforemは今でもRailsとPreactを使っていて、そこで「Islands Architecture」を採用し、開発が進められています。
Islands Architectureについてざっくり
ページ内でサーバー側でレンダリングされる静的な部分とインタラクティブなアプリの部分をそれぞれ独立して表示させる手法です。
静的な部分を海に見立て、海に浮かぶ島(islands)というイメージでアイランドアーキテクチャと名付けられているようです。
Foremでは「できるだけRailsでレンダリング」を行い、より複雑な機能であったりをPreactでレンダリングするというスタンスでやっています。
詳しい「Islands Architecture」については、Foremの説明ページであったりを読んでいただければと思います。
Islands Architectureについて(英文)
foremでのIslands Architectureの説明(英文)
foremでのPreactの説明(英文)
ここでお断りしておきたいのは、このIslands Architecture自体は他のモダンなフロントエンドフレームワークであったり、
ライブラリでも度々言及されるアーキテクチャなのですが、今回はその文脈では利用しないのでご了承ください。
あくまでも 「昔ながらのMPAアプリケーションとUIライブラリ」 を組み合わせるための手段として扱っていますのでご了承ください。
また、筆者はサーバーサイドが中心のエンジニアであることを前提としてこの記事が書かれていることをご理解ください。
このアーキテクチャのメリット
サーバーサイドレンダリングのための技術スタックを増やさなくてよい
Next.jsは「Vercelに任せる」ということもできるけど、採用する技術についてはできる限り少ないほうがいいと思ってます。
弊プロダクトには携わるエンジニアの数もそこまで多くなく、NuxtやNextだったりの今どきなユニバーサルJSについて知見が合ったり、運用経験のあるエンジニアは居ません。
そう考えると、これまでのRailsアプリケーションで運用できるというのは大きな運用コストに対するメリットになります。
ある程度自分たちで技術選定をコントロールできる
特に昨今のVercelのNext.jsでの方向性については、同意しかねる部分もあり、Not for Meであること、1年以内の比較的短期間の間で様々な仕様変更があったり、これをコントロールできないのはプロダクト開発においてはあまり健全ではないと感じてしまったためです。
したがって、そういった意味での不安定さにあまり付き合っていくモチベーションもないし、人員もいない中でそういったライブラリに依存するのは大変危険であると判断しました。
ある程度自分たちで技術選定などをコントロールできることに越したことはないので、これは私達に取ってはメリットになると思いました。
安全にコンポーネント分割できる
実際にislandsが画面にレンダリングされるちょっと前くらいまで、必要なJSファイル群を読み込まないなどの対応は可能かと思います。
もちろんユニバーサルJSに比べてできないことだったり、少しUXが劣る部分があるのは間違いないです。
インフラの構成を複雑にすることなく段階的に置き換えが可能
RailsがサーバーでHTMLをレンダリングするようなアプリケーションを段階的に移行する場合、
ロードバランサーだったりで、ページによってサーバーをバランシングしたりと事前の準備が必要です。Islands Architecture自体は特別なものではないので、MPAのアプリケーションであっても「ある程度すぐに」始めることができるので、始めるハードルが低いのもメリットかと思われます。
Islands毎にフロントエンドのライブラリをある程度自由に選択できる
Islands毎にReactを使ったり、Vueを使ったりということは「論理上」可能だと思います。
したがって、Islands Architectureを使う場合は、Vue -> Reactに移行したくなった場合に、段階的な移行も可能で共存も現実的かと思います。
このアーキテクチャのデメリット
レンダリング方法により利用する記法が異なる
フロントエンドエンジニアがerbを書かなければいけない
Railsでレンダリングする画面がある以上、フロントエンドエンジニアであってもサーバーサイドレンダリングを行う場合はどうしてもRailsのerbを書く必要があります。記法自体はそこまで難解であることはないですが、フロントエンドエンジニアにとっては「erbを書くこと自体が開発者体験を損なう要因」であると私は考えています。
1-2. コンポーネントによってはロジックが重複してしまう
RailsのViewとReactやVueのコンポーネントで同じようなコンポーネントが実装される場合は、同じようなコードが重複してしまいます。これはforemでも言及されている課題で、このアーキテクチャであれば仕方がないことだと思っています。
どの画面や機能をUIライブラリで実現するか、VanillaJSで実現するかを考えないといけない
すべてVueやReactのフルSPAであったり、NuxtなどのユニバーサルJSの場合は、テンプレートエンジンは1つなわけでいいですが、このアーキテクチャの場合は少なくとも2種類の選択肢があります。
- RailsのテンプレートとVanillaJSを組み合わせたもの
- フロントエンドのコンポーネントを利用するもの
エンジニアはこれらの中から最適なレンダリング方法を検討して、実装しなければいけません。
もちろんガイドラインであったりでも解決できるかもしれませんが、この「考えなければいけない」という状況そのものが複雑であり、「開発者体験を損なう要因」であるという認識です。
元々SPAが主戦場のフロントエンドエンジニアであったり、SPA以前のWebアプリケーション開発を知らないエンジニアにとっては、Railsでレンダリングすること自体が体験を損なう要因、気持ち悪さなのかなと思っています。
総括
サーバーサイド・フロントエンドを分業をしない組織の場合に向いている可能性がある
ここまで、サーバーサイドとフロントエンドを分離したくないということであれば、Hotwiredを選択したいところですが、UXであったりに対して縛りが発生するので、Webアプリケーションとしては現実的ではないこともあるかと思います。その場合はこのIslands ArchitectureでVueやReactの学習をある程度行って、サーバーサイドエンジニアもフロントエンドを実装してもらうという選択はいいのかなと思っています。
インフラの構成を複雑にしないためにフロントエンドの開発者体験を損なうことになる
昔ながらのRailsアプリケーションがWebAPIもレンダリングすれば、Viewのレンダリングを行うというアーキテクチャになっているので、Nodeのサーバーを用意する必要がないのは大きなメリットになります。
しかし、VueやReactで実装したり、RailsがレンダリングしたHTMLをVanillaJSで加工したりと「実装する内容によって考え方を変えなければいけない」事自体は「フロントエンドでの開発者体験を損なう」ことになるのでこれはデメリットと言えるでしょう。
個人的には
個人的にはサーバーサイドが主戦場にしているエンジニアで、弊プロダクトは現在はMPAで構成されている部分があり、あまり採用する技術スタックを複雑にしたくないというモチベーションが大きかったです。
ある程度技術スタックを自分たちでコントロールできるようにしておきたいことを考えると、
かなりメリットの大きい選択であると思い本格導入に向けて検討を進めている段階です。
次回
ここまでで、Forem流のIslands Architectureのメリットとデメリット、考え方であったりを説明していきました。
その上でMPAの延長線上で、このIslands Architectureの考えを導入していくか、モダンなフロントエンドスタックに全面的に置き換えるか?というのは興味深いのでなにかしらでご意見もらえると嬉しいです。
このForem流のIslands Architectureを実現するためのCustomElemetsを使ったライブラリをどう作ったかについて書こうと思っています。
Discussion