こんにちは!@h_noson です。「estie マーケット調査」というプロダクトのTech Leadをしています。
今回はフロントエンドのテックスタックをVue.jsからReact + Next.jsへ移行した話をします。
estie マーケット調査はestieの主要なプロダクトで、開発が始まった4年前から多くの機能が追加・変更されてきました。顧客にとってサービスがより良くなっていく一方、技術的負債が徐々に溜まっていました。今回はその技術的負債を解消するための取り組みになります。
タイムラインは下記の通りです。Vue3からNext.jsへの移行は3ヶ月強で完了する予定でしたが、結果的に1年かかってしまいました。
2022年12月 | Vue2からVue3への移行開始(@h_noson 入社) | 2023年1月 | Vue3へ移行完了 |
2023年5月 | React + Next.jsへの移行を決定、開始 |
2024年5月 | React + Next.jsへ移行完了 |
Vue2からVue3への移行
Vue2のEOL (End of Life) を見据えて、2022年12月、Vue3への移行をはじめました。このとき、「Reactがよいのでは」と意見がありましたが、EOLも迫っているのでまずはパッとVue3に移行しよう、と判断されました。
この記事の本筋ではないので簡潔に移行した感想をまとめます。
- Composition APIの書き味が良く、TypeScriptとの相性も改善されていた
- reactivityに癖があり、Proxyによる状態管理が直感的でなかった(Reactに慣れているからかもしれない)
- 双方向データバインディングの仕様変更で、ビルドは通るが期待通りに動作しなくなった。その要修正箇所を洗い出すのが大変だった(テストを書けという話ではありますが…)
- 破壊的変更があるためVue2のライブラリはそのまま使えず、Vue3に対応しているものが少なかった
- 例えばestie マーケット調査ではGoogle Map上に建物をプロットすることがあるが、そのマーカーをまとめるために必要なMarkerClusterを十分に使えるVue3のライブラリがなかった。また、活発に開発されているGraphQL clientはurqlのみだった(Next.jsでもurqlを使うことになるが軽量な上に機能も十分でとても良かった)。
Next.jsへの移行
Vue3で数ヶ月間開発を進めたのち、2023年5月にReact + Next.jsへの移行を決定しました。理由は以下の通りです。
- 他のプロダクトではReactを採用しており、共通コンポーネントをライブラリとして配布することにより開発が効率化され、デザインを統一できる
- Reactのほうが習熟しているメンバーが多い
- (改善されたとはいえ)Vue3よりもReactのほうがTypeScriptとの相性がいい
- Vue3に比べ、Reactはライブラリが豊富
- 技術的負債を抱えており、開発効率を上げるためには大きなリファクタリングが必要だった
移行開始
移行を本格的に始める前にいくつかのページを置き換え、このペースであれば3ヶ月で終わるだろうと見積もりました。新機能開発をやめ、フロントエンドのみの変更にとどめる前提でReact + Next.jsへの移行をはじめました。また、同時にUIをリニューアルしました。それまで顧客の要望に応えて機能を追加していった結果、プロダクトが “100徳ナイフ” になりかけていたことが既に問題として上がっており、必要な機能を総合してUIを1から考え直す良いタイミングであったためです。
段階的なリリース
nginxでNext.jsとVue.jsにpathを振り分けて、ページ毎にリリースしました。
pathでの切り分けが難しいケースではFliptを使ったfeature flagで切り替えました。リリース単位を小さくすることで、切り戻しを楽にしたり移行リスクを減らしたりしました。大きな機能をリリースする際にはビジネスメンバーも含めてBug Bash(社内ではQA会と呼んでいる)を行い、リリース前にバグがないか徹底して確認しました。また、Vue3移行時の反省を生かしてE2Eも含めたテストを書きながら進めました。
実際、大きな問題の発生を未然に防ぐことができました。細かい単位でリリースしたことで一度にQAする範囲が狭くなり、QAの質を高められたことも要因の1つだと思います。
また、途中から新規機能開発も並行して進める判断になりましたが、path毎にリリースすることによりNext.jsでのみの実装で十分になり、無駄な工数をかけず新規機能開発を進められました。
反省点
先ほど触れたように当初は3ヶ月強で完了する予定でした。しかし、結果的には1年かかっています。
なぜこれほど想定と差が開いたのか。
バックエンドの変更が必要になったことで工数が膨れた
フロントエンドのみの変更にとどめる予定でしたが、UIのリニューアルに伴いバックエンドも改修せざるを得ませんでした。そもそも、技術とUIを同時に刷新することに是非はあります。ただ今回は結果としてユーザビリティが向上し、その後生まれた新プロダクトのほぼ全てに取り入れられたため良い投資ではあったと思っています。
反省すべきは見積もりが大きく外れたことです。デザイナーの構想をもとに会話し、実現に足りないAPIの肌感を得ていたらより正確に見積もれていたはずです(デザインと実装をほとんど同時並行していたため、既に作成されたデザインから開発全体を見通すことはむずかしかった)。
オーナーの不在の期間があった
メンバーの出入りが多く、実装するメンバーが7人ほどになることもありました。機能毎にいくつかのグループに分かれたのですが、仕様や進捗の整理が不十分なまま複数人で取り組んでしまい、手戻りやコンフリクトが発生することがありました。
チーム内で振り返り、仕様や進捗管理に責任を持つひと(エピックオーナー)を決め、改善することができました。誰しもがオーナーシップを持つべきという話はありつつも、明示的にオーナーを決めることは大事だと感じています。
新機能開発を止められなくなった
移行中は新規機能開発を止める予定でしたが、それは3ヶ月で移行を終わらせることが前提でした。3ヶ月以上かかるとわかった時点で、移行を進めながら特に重要な新機能の開発も並行して行うことを事業部として判断しました。新機能としては、認証基盤の移行、データ拡充、顧客要望の多い機能の開発など重要なものばかりです。
その後、私を含め数人のメンバーは基本的に新機能開発に集中しました。当初のメンバーのまま移行していた場合、移行にかかる時間は8ヶ月程になっていたと思います。
成果
反省はありますが、うまくいったことも多いです。特に2つを紹介します。
開発スピードの向上
定量的な指標では見られていませんが、Next.jsに移行する理由として先ほど挙げた効果をすべて実感しています
- estie内でライブラリとして共通コンポーネントを配布して、開発効率化、デザインの統一
- Reactに習熟している開発メンバーが多く、単純に実装スピードが速い、負債を生まない設計の知見を持っている
- TypScriptの型に頼り実装効率の向上、バグの減少
- ライブラリの選択肢が多い
他プロダクトのUIのベースになった
estieが提供するサービスは不動産を扱うため、建物を検索して地図上にプロットする体験は共通する傾向にあります。estie マーケット調査でつくり上げた資産は、他のプロダクトのNext.js移行や新規開発のベースとして実際に活用されています。逆に、他のプロダクトからestie マーケット調査に輸入した機能も少なくありません。
まとめ
1年の時間がかかってしまいましたが、結果的にユーザビリティが上がって良いプロダクトになりました。移行が中途半端なままで技術的負債になることもあるため、最後までやりきれた意義もとても大きいです。再び大きな移行が必要になった際は、今回の反省を生かして取り組めたらなと思います。
最後に
estieではVue.jsで実装されているプロダクトがほとんどなくなり、新規プロダクトもNext.jsで開発が進んでいます。Next.jsで開発したい方、是非カジュアル面談しましょう!