新規プロダクトのフロントエンド構成を見直したお話
初めまして。映像制作向け新規プロダクトの開発をしている八木澤です。
新規プロダクト開発チームでは、バックエンドをAWSのAmplifyで、フロントエンドにはNext.jsを使用して新規プロダクトの開発をしています。
今回はフロントエンドの構成を見直し再構築したので、私たちのチームが使用している構成を紹介していきます。
背景
現在開発している映像制作向け新規プロダクトは、開発をスタートしてからPoCを行い、その結果を踏まえた機能改修を行うタイミングでフロントエンドの構成を見直しました。
見直しを行う上で下記のポイントを押さえながら技術選定をしました。
- サービスのUX向上
- サービスの速度改善
- 開発生産性の向上
- コードの可読性を上げる
- 簡潔なコードが書けるライブラリ選定
サービスの観点では、PoCの結果を踏まえてプロダクトの速度を速くする必要が出てきており構成とフロントエンドの設計の見直しを行いました。(設計のお話はまた別記事で)
また開発体制として、オフショアを利用して開発を進めており、コードレビューなどを弊社のメンバーで行なっております。
このため、コードの可読性を高く維持してレビューの時間を減らしたい、簡潔に書けレビューしやすいコードを作りたいという要望がチームでありました。
上記を踏まえて技術選定をしましたので、そのご紹介をしていきます。
構成の比較
こちらが構成の比較になります。
今回は基本的なTypeScript + Reactの構成は崩さずに、開発で利用するフレームワークやライブラリの見直しを行いました。
TypeScript
React
Yup
+ Next.js
+ React Hook Form
- Formik
+ Jotai
- Redux Toolkit
+ Apollo Client
+ Tailwind CSS
変更の理由などは項目ごとに触れていきます。
Next.js
- Next.jsが提供する機能により、UXと開発生産性を良くしてくれる
- 元々は
create-react-app
で環境を構築しておりSPAを採用していたが、初回描画が遅かった(APIのデータフェッチ部分などの処理が多すぎたという設計の問題あった) - 初回描画を高速に行えるSSRへ変更し、ユーザー体験を良くできる
- ファイルベースルーティングによりルーティングの設定が楽になる
- ゼロコンフィグで初期設定が簡単かつ自身での拡張ができる
- 元々は
- 社内の別プロジェクトで採用されており知見があった
- チーム間の知見共有でき、開発の際の障害を相談できる環境があり導入のハードルが低い
また、コードデプロイをAmplifyの方で設定しているのですが、Amplifyの設定にNext.js用の設定がありデプロイ周りでのハードルが低かったのも導入を進められた理由の1つです。
React Hook Form
- 再レンダリングがFormikより少ない
- 不必要なレンダリングを抑えることができる
- 日本語のドキュメントがある
- メンバーのキャッチアップが比較的容易である
Jotai
- Redux Toolkitよりコード量を削減できる
- ReduxではActionsやReducerなどを記述すると単純な記述量が増える
- その結果コードを追うのが大変になる
- 状態管理で必要な項目が少ないため、Reduxではオーバースペックになる
- アプリの規模が小さいかつstate管理する項目を見直した結果、状態管理する項目が少なくなった
この項目ではチーム内で賛否があり、「Jotaiではatom単位の管理が大変になるのでは?」という声も上がっていました。
しかし、プロジェクト自体で状態管理する項目が少なく、現状そこにあまり工数をかけたくなかったのでJotaiを選択しました。
Apollo Client
- GraphQLのschemaからAPIのfetch部分のコードを自動生成
- バックエンドをAppSyncのGraphQLで組んでおりコードの自動生成が可能
- Amplifyが提供しているコードジェネレートもあったが、Apollo ClientであればAPIリクエスト部分まで自動生成され開発工数の削減が見込める
- 型定義も自動生成
- GraphQLからAPIが使用する型を自動生成してくれており、型安全に開発を進めることができる
- キャッシュ機能があるため、新たなライブラリを導入する必要がない
- APIのレスポンスをキャッシュしておくことができ、リクエスト数を制御できる
- React Queryなどのライブラリの検討もしていたが、Apollo Clientでまとめることができる
本プロダクトではGraphQLを採用しており、データフェッチ部分の処理をほとんど自動生成しており工数の大幅削減ができました。また、APIのInputの型やレスポンスの型も同時に生成してくれているので別途型定義を増やすことなく開発を進められています。
Amplifyを使用しており、独自のschema設定からバックエンドリソースを作成していますが、独自定義部分があるので自動生成する際に工夫が必要でした。この部分は別記事にて紹介できたらと思います。
Tailwind CSS
- cssの複雑化を防ぐため
- チーム内でcssに詳しいメンバーがいなかったので、全てcssで管理すると管理しきれなくなる
- コンポーネントでスタイルを読み取れるので、複数ファイルを参照する必要がなくなる
Amplifyを使っているのであれば、figmaと連携させてAmplify UIでコンポーネントを生成してコード量を減らすことも案として上がりました。
しかし、生成されるコンポーネントがJSXで出力され型付けをする際にIF層が必要となり冗長になる、コンポーネントを管理できる人材がチームにいない等の理由で断念しました。
またChakra UIの検討も行いましたが、今回SSRでレンダリングを行うためより軽量なライブラリであるTailwind CSSを選択しました。
まとめ
- サービスの速度が上がった
- まだまだ開発は続いているが、既に現時点でPoC前より速度が出ているのである程度の効果を実感できている
- コードが読みやすくなった
- 以前のコードは何をしているのか追うのが大変だったが(特にRedux系)、現状は各機能何をしているのか追いやすいようになってきている
- 今後は共通化などのリファクタリングを行い、更に読みやすくしていきたい
開発生産性は設計も含めてなので、日々改善を繰り返してより良いコードを作っていきたいです。
まだまだ仮説検証が多いプロダクトなので、最終的にユーザーの価値になるプロダクトを作っていきたいです。
またプロダクト間の情報共有が少しずつ出てきたので、開発チームのノウハウを積んでいきたいです。
参考になる情報が少しでもあれば幸いです。
Discussion