はじめに
こんにちは、株式会社キカガクでエンジニアをしている北田です。
ついにキカガク開発チームでも技術ブログを開設しました!(祝)
先日、私たちが提供する E ラーニングプラットフォーム【キカガク】は Vue (Nuxt.js) → React (Next.js) への技術刷新と既存コードの大幅リファクタリングを目的として技術リプレイスを行いました。
今回は、リプレイスの決断理由やリプレイスを通して苦労した点などを書いていこうと思います。
※ この記事では詳細な実装内容やコードなど、深い技術の話はしません。
対象読者
- 普段から JavaScript (TypeScript) で開発をしている
- レガシーな言語からモダンなフロントエンド言語への変更を考えている
- React、Next.js でプロダクト開発を進めていきたい
- フロントエンド言語の技術選定に迷っている
リプレイスの決断理由
React, Next.js のエコシステムの充実
React と Vue の検索トレンドをnpm trends で比較してみましょう。
日本では比較的 Vue を用いたプロダクトが多いとされていますが、過去5年間の世界の検索トレンドを見を見ると React が世界的にモダンなフロントエンド言語して、より多く取り入れられています。
2022年 5 月時点で React の最新バージョンは v18.1.0 、一方の Vue は 2021 年 6 月以降最新リリースがされておらず v2.6.14 となっています。このように、React が今後のフロントエンド開発において最前線となることを予想し、キカガクは React を導入しようと決めました。
パフォーマンス改善
サービス全体のパフォーマンス改善もリプレイスを決断した大きな要因です。
キカガクでは動画やテスト、またそれらに使用する資料といったデータを持つ様々なコンテンツをダッシュボードなどで表示する必要があります。下記画像はキカガクのダッシュボード画面です。
ユーザーによっては表示するコンテンツがとても多いため、それによって初期表示が大幅に遅くなることがありました。
Next.js 以前に JavaScript に大きく関わることかもしれませんが、冒頭にも書いている通りリプレイスを期に多くの関数をリファクタリングや最適化する目的もあったためリプレイスを決断しました。
はじめは事前のビルドで静的ファイルを生成してくれることで、ページの初期表示を早くする SG (Static Site Generation) を各所で取り入れる予定でしたが、結局のところキカガクではユーザーの動的アクションによる表示値の変更がほとんどのコンポーネントで必要だったため、取り入れることはできませんでした。涙
それでも結果的に今回のリプレイスを終えて、サービス全体のパフォーマンスは改善されました。
更に最適化できる箇所もあるため、引き続き行っていく予定です。
パフォーマンス改善について詳しくは別の記事にまとめたいと思います。
キカガク開発チームのモダンな技術への興味・関心
リプレイス決定の理由で、一番最初の「React, Next.js のエコシステムの充実」の恩恵を受けているのは当然開発者である僕ら開発陣も同じです。
私が入社した当初は Vue/Nuxt.js で開発していたメンバーの中には、個人開発で React を触っていたり、React を学習するコミュニティに参加していたりと、積極的に社外の技術インプットも行っていました。
そういった背景から、技術リプレイスを行うことに対しても悲観的どころか賛同的な意見ばかりだったためリプレイスを行うことになりました。
新しいことを学ぶのは、いつでも楽しいですよね!
採用活動
プロダクトの成長に伴って、キカガクではつよつよなエンジニアを積極的に採用していきたいと考えています。
そんな中で、React/Next.js の知見を持つエンジニアを採用できるように、というのも私たちが Next.js のリプレイスを行う理由の1つです。
例えば Wantedly で自社開発のフロントエンドエンジニアの募集要件を探してみると、React/Next.js と書いてある募集が多く目につくかと思いますが、そのような募集に対する応募件数も Vue/Nuxt.js に比べると多いのが現状です。*キカガク調べ
キカガクでは入社後に言語のインプット期間を設けていますが、これまでの React/Next.js の経験を入社後の開発でもすぐに生かせるという意味で、言語リプレイスは必要だったと改めて感じました。
キカガクの開発初期の Vue/Nuxt.js の選定理由
唯一「キカガク」リリース当初から開発していた弊社 CTO 祖父江が書いた記事で詳しく解説しているので、気になる方はぜひこちらの記事もチェックしてみてください。
苦労した点
独特なJSX 記法
慣れの問題ではある気がしますが、キカガクのリリースからおよそ1年間 Vue で書いていたメンバーからするとその記法になれるまでに時間がかかったと思いました。
それぞれの記述方法は実装の具体的な内容になるため、ここでは割愛しますが、Vue では1つのファイルに書くことができるのは1つのテンプレートのみで、それに対してJSX では1ファイルに複数のコンポーネントを書くことができます (下記画像) 。ある種コンポーネントを関数のように書くことができます。さらに大きなくくりだと、これまで1つの .vue ファイルに書いていたプレゼンテーション、ビジネスロジック、データ層をどう切り分けるかがなかなか定まらないまま初めは実装を進めていたので、その点は苦労したと今振り返ってみると感じます。
そもそもリプレイス前の1つの Vue ファイル内の構成はおおよそどのファイルでも下記の図のようなもので、ビュー、ロジックがすべて1つの Vue ファイルで行われていたので、見通しがよくありませんでした。
ディレクトリの構成についても記事を書くことができそうなので、また後日別の記事でまとめたいと思います。
状態管理
状態管理についても、Vue と React では若干異なります。
状態管理を大きく分けるとローカル、そしてグローバルの2つがあります。
ローカルに関して、これまで Vue ではその状態管理を各ファイルで変数として持つことで管理をしていました。Vue では変数とセットで存在するセッター関数がないので、どこで状態の更新をおこなっているか非常にわかりづらくなっていました。
一方の React では基本的に hooks を使用します。ローカルでは useState や useRef を使って管理を行います。useState では変数とそれを更新する set関数 が存在するので、非常に見通しが良くなりました。
グローバルな関数(ユーザーの認証状態など)に関しては、Vue では Vuex という状態管理のライブラリを使用していました。Vuex に関しては非常にシンプルな使い方ができていましたが、React では useContext という hooks を使っていたり、Recoil というこれまた状態管理のライブラリを適所で使用したりとその管理、使い分けが最初は非常に苦労しました。
また、はじめに「React, Next.js のエコシステムの充実」とお話しましたが、それが故に他にも Redux というものを使うべきか悩んだりと、充実している分何ががキカガクにとってベストなのかの解を模索する時間がかなり必要でした。
ライブラリ
キカガクではいくつか外部の優秀なライブラリを使用しています。
当然そのライブラリは Nuxt.js で動くものであっても、 Next.js で必ず機能するとは限りません。なぜなら、Next.js では SSR がデフォルトの挙動になっているからです。
そのため、もしライブラリ自体が SSR に対応していないものだと、こちら側でその設定を追加する必要が出てきます。
設定に工夫が必要というだけでなく、そもそものライブラリ自体のバグで動かないこともあるため、そのままリプレイスできないものがないか、調査が大変でした。
幸いキカガクで使用しているライブラリはすべてこちら側の設定でなんとか使用することができましたが、仮に使えないものがあった場合、別のライブラリを使用するか、自分たちで実装するかを検討する工数が必要になってきます。
Advanced Features: Dynamic Import | Next.js
さいごに
リプレイスプロジェクトは時間もかかり、想像以上に大変な作業の連続でした。
それでも、プロジェクトに携わったメンバー全員がより言語の特性を理解しそれらを実際のコードの落とすことができたとても素晴らしい機会でした。
なかなかサービスの技術選定を変更することはないので、開発メンバーの知見が貯まるいい時間になったと今では感じています。
もしこれから技術選定を考えていく方がいれば、ぜひ参考にしてみてください。
今回はざっくりとした内容で書きましたが、キカガク開発事業部ではこれからもどんどん技術記事を書いていくので、ぜひチェックしてみてください。
エンジニアも採用をおこなているので、興味があればまずはカジュアル面談でお話しましょう!