meepaのフロントエンド刷新プロジェクト vol.1 -課題整理とフレームワーク選定-
dotDの松村です。meepaの開発を担当しています。
まだまだ発展途上のmeepaですが、何度かPoC検証と、その結果をもとにした機能追加を行なっていく中で、技術的な課題も出てきています。
ユーザーの使いやすさ向上とプロダクトの成長を加速させるために、フロントエンドのフレームワークを導入することを検討しています。
本記事では、現状のmeepaの課題と、フレームワーク選定にあたってどんなことを考えたのかを書き残します。
その前に、meepaのフロントエンドの変遷を振り返ってみます。
meepaとは?
meepaは、お子さんの「本当の好き」を見つけるために、色々な習い事や課外活動を気軽に試せるようにすることを目指した課外活動マッチングサービスです。
2021年2月ごろからMVP(Minimum Viable Product)を作り始め、PoC(Proof of Concept = 概念実証)をしながら徐々にアップデートしていっています。
meepaフロントエンドの歴史
PoC#1: LINE Flex Message
最初は、LINEのFlex Messageというレイアウトをカスタマイズできる機能を使って、ユーザーにレッスンの情報を送信していました。
最初の構想から、体験レッスンのレコメンドから予約完了まで、ユーザーとのやり取りはLINE Messaging APIを使ったBotで実現しようとしていたので、最小構成で実現できる方法でした。
しかし、これでは表示できる情報量に限界があり、ユーザーとしても判断材料が少ない状態になっていました。
PoC#2: Google Apps ScriptによるHTML生成
Flex Messageの短所を改善するために、スプレッドシートにまとめたレッスンの情報をもとに、おすすめレッスンの一覧とその詳細ページのHTMLを、Google Apps Script(GAS)で生成するようにしました。
GASのHTMLテンプレートを使用していたのと、機能的にもそんなに多くなかったので、フレームワークは使いませんでした。
しかし、GASの処理速度が非常に遅く、一覧ページを開くのに、1分以上掛かるケースもあったため、GASを脱却することにしました。
現在: AWS S3からの配信
現在はバックエンドをスプシ + GASから、AWS RDS + Lambdaに移行したタイミングで、フロントエンドもAWS S3に配置することにしました。
GASを使っていた時は、おすすめレッスンの一覧と詳細ページのみでしたが、現在は機能も増えて、ユーザー認証〜レッスンの検索〜体験レッスン予約までWebから出来るようになっています。
この切り替えのタイミングで何れかのフレームワークを導入できればよかったのですが、検証速度を優先してGASで吐き出していたソースコードを引き継ぐ形になってしまい、技術的負債として徐々に負担になってきています。
現状の課題
現状、meepaのフロントエンドが抱えている問題は大きく下記の3つです。
表示速度
表示速度はGASを使っていた時に比べたら格段に早くなりましたが、世の中のサービスと比べるとまだまだです。
表示速度は継続率や離脱率に直結するので、どんなサイトを作るにしても早いに越したことはないです。
フロントエンドとAPIが連携してビューを構築しているので、フロントエンドだけで全てが解決するわけではないですが、フロントエンドの処理速度を上げる = 表示速度を上げることに繋がるはずです。
SEO対策
SEO対策として、コンテンツ面の対策も必要です。HTMLタグの最適化は実施していますが、そもそも現状はクライアント側のJavaScriptでAPIと連携してビューを組み立てるCSR(Client Side Rendering)となっているため、ほぼ空っぽのHTMLが配信されているのは改善した方がよさそうです。
均質な開発
ここまではフロントエンドエンジニアはほぼ1名の体制でしたが、開発規模が大きくなれば当然関わるエンジニアも増えてきます。
また、meepaの開発チームはフロントエンド /バックエンドという垣根無くエンジニア全員が両方見れるようになることを目指しています。
現状はノンフレームワークなTypeScriptでSPA(Single Page Application)を構築しており、メンバーのスキルレベルによって、コーディングに差が出やすくなっています。
フレームワーク選定
ということで、フレームワークを導入することにしたわけですが、今回はNext.jsを採用しようと思います。
今からフロントエンドのフレームワーク導入するとなった時、候補としては
・Vue / Nuxt.js
・React / Next.js
の2つが候補に上がると思います。
Nuxt.jsは弊社のonedogで使用した実績はありますが、Next.jsを選択した理由としては3つあります。
1つ目は、バックエンド側でレンダリング処理を行い、生成したHTMLをクライアントに返すSSR(Server Side Rendering)に対応していることです。
今までブラウザで行っていたビュー構築をバックエンド側に持っていくことで、表示速度やSEO面で大幅な改善が期待できることです。
これはNuxt.jsも同様なのですが、onedogの場合はSPAモードで動かしていたので、SSRの実績はありませんでした。なので、SSRに対応しようとした場合、Nuxt.jsもNext.jsも社内の知見としてはあまり変わらない状況でした。
2つ目は、SSR、SSG(Static Site Generation)、ISR(Incremental Static Regeneration)という3つのレンダリング方法をページ単位で選択できることが、meepaの仕様に合っている点です。これはいまのところ、Nuxt.jsでは出来なさそうでした。
meepaの場合、レッスン一覧やユーザーのプロフィールページのように、ユーザー毎に動的にコンテンツを切り替えるページは、リクエスト毎にバックエンド側でHTMLを生成するSSRが向いています。
一方で、レッスン詳細ページは、全ユーザー共通ではあるものの、不定期で情報の更新やレッスンの追加・削除が発生する可能性があるため、一定時間ごとにデータを再取得し、バックグラウンドでHTMLを生成し直すISRを適用できると良さそうです。
また、利用規約やLPなどの静的なコンテンツかつ更新頻度の低いページは、Build時に一度だけHTMLを生成し、リクエスト時は生成済みのHTMLを返すSSGが向いています。
3つ目は、トレンドの変化です。
日本国内では、少し前までは Vue.js / Nuxt.jsが人気でしたが、ここ最近は React.js / Next.jsが逆転しており、リファレンスも増えてきています。
おそらく前述のページ単位でのレンダリング方法選択を含むバージョンアップが、かなり優秀だったことで注目度が上がったのではないかと推測しています。
また、世界全体では依然としてVue.js / Nuxt.jsより、React.js / Next.jsの注目度の方が高いです。
「そんな理由?」と思われるかもしれませんが、Web技術、特にフロントエンド領域はトレンドの変化が早いので、トレンドを取り込んでいくことが、エンジニアの採用強化になりますし、今在籍しているエンジニアの技術力向上にも繋がると考えています。
まとめ
meepaではフロントエンドの負債解消やカイゼンに向けた活動を始めています。移行作業の状況についても、引き続き発信していければと思っています。
最後に、dotDでは一緒に事業開発をゴリゴリ進めていく仲間を募集中です。
弊社サイトもしくはWantedlyから是非ご応募ください!