LCL Engineers' Blog

バス比較なび・格安移動・バスとりっぷを運営する LCLの開発者ブログ

「バス比較なび」リファクタ始動:なびリプレイスプロジェクトの全体方針

振り返り:私たちの歩み

LCLでフロントエンドエンジニアをしている川辺です。 この記事ではバス比較なびという弊社の主力サイトをリプレイスしていった体験を紹介します。

※内容的にはリプレイス作業なのですが、社内ではリファクタプロジェクトと呼んでいるので、今後もこの記事では「リファクタ」と表現します。

前回の記事ではリファクタリングの必要性や過去の失敗ケースを紹介しました。

techblog.lclco.com

簡単におさらいすると、リファクタをせずにいると以下のような問題が発生します。

  • サイトを改修する作業に時間がかかってしまう
  • サイトに何かしらの変更を加えたときにバグを発生させる可能性が高まる
  • 一部のエンジニアしかコードの意味を理解できず触ることができない
  • 古いコードやライブラリが使われ続けることで、セキュリティリスクが高まる
  • 世の中の進化についていけなくなることで競争力が下がる
  • Application Service Provider (ASP)を思うように導入できない

そして、上記の問題を解決するためにサイトに部分的にReactを導入する新規で作成するページやコンテンツはReactで書くようにするなどを試みていったのですがうまくいかなかった話をしました。

リファクタリングをする目的は技術的負債を解消することです。 技術的負債を解消することで、開発速度が向上し、その結果、より速くユーザーに価値を届けることにつながります。

我々の会社は長い間、技術的負債を解消するために様々な試みを実施してきましたが、これまでの取り組みは成功に至りませんでした。しかし、今回の技術選定は、これまでにないドラスティックな変更をもたらすものになりました。

まずはどのような過程で技術選定をしたのかを見ていきたいと思います。

技術選定の物語:私たちの決断

リファクタ前の比較なびの現状はRails + jQuery(一部React)で実装していて、フロント部分はERBもしくは jQueryまたはReactで書かれています。 一部のページでは歴史的な経緯もありますが、ユーザービリティとSEO対策の両立を目指した結果、初回ロード時にはERBでレンダリングし、その後インタラクティブに応じて画面を更新するためにjQueryで再度レンダリングする、非常にメンテナンス性の悪い構造になっています。

フロント側の課題としては以下のようなものがありました。

  • ERBやjQueryやReactとページによって記法・ライブラリや設計概念が異なっていてわかりづらい
  • そもそもjQueryがわかりづらい
  • ERBとjQueryで同じような処理を書いていたりするのでダブルメンテになっている、また対応漏れも発生しやすい
  • 過去のリファクタプロジェクトの影響でディレクトリが散在している
  • ERBを使う部分については、Rubyの知識が必要であり、現代の一般的なフロントエンドエンジニアの技術スタックから外れていて、市場とミスマッチが起きている
  • 歴史的にも長らく様々な方法でメンテナンスされていることで、コードを実行してみないとどんな動きをするのかわからない

技術的負債やコードの複雑性が増大している現状では、リファクタリングには高いコストと難易度が伴います。加えて、たとえ大きな投資をしてリファクタリングを実施したとしても、技術スタックが現代のスタンダードから大きく乖離しているため、その費用対効果は低い可能性があります。このような状況を鑑みると、既存のコードベースのリファクタリングよりも、フレームワークを変更して一から作り直す方が最適な解決策じゃないかという結論に至りました。

その時はNext.jsとNuxt.jsが広く使われていたのでなびでもNext.jsとNuxt.jsのどちらにするかの検討になりました。

Nuxt.jsは数年前に別のサービスで実装実績もあって知見もそれなりに溜まっていました。 Next.jsはこのプロジェクトの少し前にリリースしたサービスをNext.jsで実装していたので、ある程度いけそうな感覚は持っている状態でした。

最終的な結論としてはNext.jsを採用しました。

採用した理由は以下の通りです。

  • Nuxt.jsはTypeScriptとの相性があまり良くない
  • Vue.jsよりもReactの書き方の方が好み
  • Next.jsの方がパフォーマンス最適化が進んでいる印象
  • Next.jsのGitHubのスター数やnpm ダウンロード数でもNext.jsの方が多い
  • 直近にリリースしたサービスをNext.jsで実装したのである程度の知見がある

なので、最終的なゴールとしてはRailsはAPIとしてだけ利用して、フロント側はNext.jsで実装する構成を目指します。

ちなみに、ディレクトリ構成やlinterの設定、playwrightでのテストやstorybookの運用などは直近にリリースしたサービスをベースにする方針でこのタイミングではあまり話しませんでした。やっていくうちに見えてくることもあると思っていたのと、何よりもスピード感を持ってプロジェクトを前に進めていかないと中途半端な状態で自然消滅すると考えていたからです。

プロジェクトの道のり:私たちの計画

今までの経験上、エンジニアだけで完結するように進めようとするとどうしても途中で他の案件に時間が奪われていって自然消滅していってしまいました。 なので今回はディレクターやデザイナーと共にしながら共通の課題として進めたいと考えていました。 しかし、問題はリファクタに膨大な時間がかかりそう(この時点ではどのくらいかかるのかさえも見えていませんでした)なことでした。

そこで一度で全てのリプレイスを完了させるのではなく、段階的にページ単位でなびの実装を置き換えていく方針を取りました。 つまり、一時的にRails環境とNext.js環境が共存することになります。 この方法だとリファクタプロジェクトが途中で止まってしまった場合、Rails環境とNext.js環境の二つが存在することになってしまうデメリットがありますが、一度で全てを置き換えるのは時間もかかる上、リスクも大きすぎるので、比較的ユーザーへの影響が小さいページから徐々に試していく方が良いだろうと考えました。 この方法だとユーザーに悪い影響が出てしまった時に容易に前の状態に戻すことができるのも大きなメリットです。

プロジェクトの進め方の流れは以下の図の様なイメージです。

また、コンテンツごとに難易度を設定して、「難易度:低」から始めて「難易度:中」「難易度:高」と開発の知見を溜めながら徐々に複雑なページを置き換えていく戦略を考えました。

開発体制の紹介:私たちの組織

ここでは、なびリファクタプロジェクトにおける開発体制とそれぞれの役割を紹介しようと思います。

デザイナーの体制と役割

当時のデザイナーはLCL全体で2人しかおらず、比較なびだけでなく全てのサービスを担当しています。

以前はユーザーエージェントでPCとスマホの表示を分けていましたが、現代のデバイスや利用シーンの多様化もあり、デザイナーと相談してレスポンシブ化した方が良いという結論になりました。

また、それとは別になびのデザインは時代的にも古くなってきたこともあったのでこれを機にデザイン面も刷新していきたいとなびリファクタプロジェクトについてもかなり良い反応を示してくれました。

バックエンドエンジニアの体制と役割

当時のバックエンドチームは3人で、それぞれアプリや他のサービスとの掛け持ちだったりして専任の担当者はいない状態でした。インフラの対応もしてくれています。

なびリファクタプロジェクトにおいては、テスト環境や本番環境の作成だったりページ単位での出し分けの設定などをしてくれました。 また、なびリファクタの相談をした時にRails側のAPIも整理したいということになったので、リファクタ用にAPIを新規で作成するのが主な役割です。

フロントエンドエンジニアの体制と役割

フロントエンドエンジニアは3人いて、それぞれのサービスごとに専任の担当者が1人いる状態でした。

基本的にはそれぞれのサービスをそれぞれの担当者が対応していたのですが、なびリファクタは規模が大きく、到底1人で対応できる量ではなかったので、必要なタイミングでは全員で一緒にやる方針でした。

自分たちがリファクタプロジェクトを発案したこともあり、開発業務以外にも進捗管理やミーティングのファシリテーションなど様々なことをやっていました。

ディレクターの体制と役割

ディレクターは2人いて、1人は部長だったので基本的にはもう1人のディレクターの方がなびのメインの担当者でした。 主な役割としては、リファクタ対象ページのコンテンツの見直しやリリース後の効果検証です。 また、リファクタプロジェクト進行中は既存の案件の対応が少なくなってしまいますが、そのことをステークホルダーに説明してくれるのもディレクターです。 ステークホルダーからの理解が得られないとリファクタを進めることができないのでとても重要な役割です。

幸いなことに現ディレクターも前ディレクターもリファクタの必要性を理解をしてくださったので、スムーズにリファクタプロジェクトを進めることができました。

もしステークホルダーの理解を得るのが難しい方がいらっしゃれば、リファクタリングの必要性に関する前回の記事を参照していただくことをお勧めします。その部分では、プロジェクトの背景や取り組むべき理由が詳しく説明されており、プロジェクトの重要性と目的を理解するのに役立つはずです。

まとめ:振り返りとこれからの展望

この記事ではなびリファクタに際してNext.jsを採用するまでの経緯や、プロジェクトを進める方針を紹介しました。

記事中では決定したことだけを書いていきましたが実際には

リファクタ方針の草案を作る → フロントチーム内で相談してフィードバックをもらう → フィードバックを元にリファクタ方針をブラッシュアップ

というプロセスを何度も繰り返したり、各部署とも何度も相談したりしながらリファクタプロジェクトの目線を合わせていきました。

この記事を書いておきながら言うのもアレですが、大事なのは方針よりも関係者全員が同じ目的を共有することだと感じました。

ある程度の規模になってくると、リファクタを1人の力で完結させるのは難しいと思います。リファクタに対して課題感を持っている人はぜひ自分の周りの関係者と相談して自分の課題をみんなの課題にしていって欲しいと思います。

次回の記事では実際になびリファクタへの取っ掛かりとなる最初の1ページ目をリファクタした時の話を書きたいと思います。 ここまで読んでいただきありがとうございました。