LCL Engineers' Blog

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

「バス比較なび」リファクタリング序章:「バス比較なび」の現状と課題

はじめに

LCLでフロントエンドエンジニアをしている川辺です。 早いものでLCLに入社して既に7年が経ちました。 僕が入社した時から今に至るまでずっと言われ続けてきたことに「なびフロントエンドの開発環境を何とかしたい」というのがあります。

弊社ではバス比較なびという高速バスの比較サイトを運営しています。

www.bushikaku.net

サービスをリリースしたのが2006年なのでリリースしてから15年以上の歳月が経ちました。 そしてフロント側はリリース時からほとんどの実装をjQueryで書かれています。 なので僕が入社した2016年頃からずっとフロントチームとしてこのレガシーなコードに対して課題を持ちつつもなかなか根本的な解決をすることができずといった状態が続いていました。

そんな中で遂に、なびリファクタリングの大きな一歩を踏み出すことができたのでいくつかのシリーズに分けて紹介したいと思います。

リファクタリングとは何か?

そもそもリファクタリングとは何でしょうか?

リファクタリングとは、「ソフトウェアの外部的振る舞いを保ちつつ、内部構造を効果的に改良すること」です。

つまりユーザーから見た時の振る舞いを変えることなく、内部の構造を改良することです。

ユーザーから見た時の振る舞いを変えない → ユーザーから見た時に変化がない ≒ 直接サイトの売り上げに貢献しない

と捉えることもできるので多くの会社ではリファクタリングみたいな業務の時間を取ることが難しいのが現状だと思います。

リファクタリングの必要性

ではなぜリファクタリングをする必要があるのかというと、リファクタリングをしないことによって問題が起こるからです。

具体的にどのような問題が発生するかというと、

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

などが考えられます。

リファクタリングしないことによってすぐに大きな問題が発生するわけではありませんが、放置し続けると誰も触ることができず最終的にはサイトを改修することが困難になったり、最悪の場合はセキュリティインシデントにつながることになります。

弊社はまだリファクタリング最中なところもありますが、リファクタリングによって以下のような効果を実感しています。

  • 開発作業の速度が向上した
  • 新しくジョインしたメンバーもスムーズに開発に加わることができた
  • リファクタに伴いテストコードを実装するようになったので変更への心理的負担が下がった
  • 採用の場でモダンな開発環境を求めている人たちが応募してくれるようになった
  • 開発に携わるエンジニアのモチベーションが向上した

リファクタリングによって、環境がモダンになったことにより生産性が上がるだけでなく、開発者のモチベーションも上がったり、採用面でもより良い人材にアプローチできるようになるという副次的な効果もありました。

過去の失敗ケース

ここまで話を聞くとリファクタリングをしたいと思ってくれる人も多いかと思いますが、弊社でもちゃんとしたリファクタリング体制が整うまでに様々な失敗がありました。 ここではどのようなチャレンジと失敗を繰り返してきたかを紹介しようと思います。

失敗ケース1:サイトに部分的にReactの導入を試みる

2016年の僕が入社したばかりの頃、React熱が高まっていて弊社でも部分的にReactに置き換えていこうということになりました。

ただ、当初はまだReactで生成したDOMをクローラーが正しくクローリングしてくれるか怪しい時でもあったので、クローリングされなかったとしてもSEO的に問題のないページを対象にして試してみました。

その結果、いくつかのページにReactが導入されたものの、サイトの主要な部分としては依然としてjQueryで実装されたままの、ReactとjQueryが混在している状態になってしまいました。

通常案件と並行してリファクタ作業をしていたこともあり、だんだんとリファクタの時間を確保できなくなってきて、最終的には中途半端な状態で残ってしまいました。

ちなみにこの時のリファクタプロジェクトでfrontendディレクトリを作成して、Reactで書かれたコードはすべてfrontendディレクトリ配下に入れるようにしたので、既存のjQuery用のディレクトリとReact用のディレクトリが二つ存在するようになってしまいました。

Reactに対する知見も不十分だったこともあり、frontendディレクトリ配下のコードもかなりごちゃごちゃとしたものになってしまいました。

なので、開発工数改善には大きく繋がらず、結果的に保守対応でも考慮する点が増えてしまいました。

失敗ケース2:新規で作成するページやコンテンツはReactで書くようにする

今回は

  • 新しく作成する部分をReactで書いていく
  • 既存のコンテンツも改修のタイミングでReactに置き換えていく

戦略で少しずつリポジトリ内のReact率を高めていくやり方でチャレンジしました。

失敗ケース1の時に懸念していたクローリングの問題も、新規追加ページなら仮にクローリングがうまくいかなかったとしても影響を小さく済ませられるので試したいという考えもありました。

この結果、一部のページやコンテンツでは良い感じに開発をすることができるようになりましたが、ReactでDOMを書き換える仕組みの都合上、どうしても初回レンダリング時に一瞬画面が真っ白になってしまう問題があり、ユーザー体験を損なってしまうのでなびのコアとなるコンテンツへの適用はできませんでした。

また、急ぎの案件だったり部分的な修正の場合は速度を優先して既存のjQueryに変更を加えることも多く、なかなか思うようにリファクタを進めていくことができませんでした。

Rails + Reactの組み合わせでリファクタ作業を進めることに限界も見えてきました。

失敗ケースの振り返り

今までの失敗ケース1と失敗ケース2についてそれぞれ振り返ってみたいと思います。

  • 失敗ケース1:サイトに部分的にReactの導入を試みる
    • Reactを導入すればコードがクリーンになると思っていたがそうではなかった
    • 通常案件と並行してリファクタ作業をしていたのでだんだんと作業時間を確保するのが難しくなっていった
  • 失敗ケース2:新規で作成するページやコンテンツはReactで書くようにする
    • Rails + Reactの組み合わせだとCLS(Cumulative Layout Shift)の問題を避けられないので使用できる箇所が限定的になってしまうことがわかった
    • 忙しくなってくると案件を進めることを優先しがちになってファクタが後回しになってしまった

失敗ケース1の時には、

jQueryをReactに置き換える → 宣言的にコードを書くことができる → コードをクリーンに保つことができる

と考えていましたが実際にはそうではありませんでした。 Reactでクリーンなコードを書くためにはコンポーネント設計や規約による縛りも必要でしたがその観点が抜けていました。

失敗ケース2では、少しずつでもなび開発環境を改善したい思いで進めていきましたが結果的に思うように進捗を出すことができませんでした。

まとめ

過去のケースを振り返ってみると、

ある程度時間的に余裕ができた時にリファクタリングに向けて動き出す → 徐々に開発業務が忙しくなってきてそちらを優先対応する → リファクタプロジェクトが自然消滅する

ということを繰り返していました。 根本的な失敗の要因としてはエンジニア内でリファクタの作業を完結させようとしたところが良くなかったと思います。

リファクタリングは想像以上に根気と労力のかかる作業です。 プロダクトオーナー(PO)の理解と協力がなければ進めることは難しいです。

幸いなことに弊社のPOはリファクタリングの必要性に対して理解を示してくれて、現在も協力してリファクタリングを進めていっています。ここについてはまた別記事にてお話しできればと思います。

次回の記事では過去の失敗を踏まえた上でどのような戦略でリファクタリングを計画をしていったかを話せればと思っています。

JOIN US!!!

LCLでは、失敗もヒントに変える挑戦者になろう というValueを掲げ、常に新しい挑戦と学びに全力で取り組んでいます。

失敗を恐れず、困難を乗り越えて成長できる仲間を募集しています。 まずはカジュアル面談からでも、随時対応していますのでぜひお気軽にお声がけください。

www.lclco.com

次の記事はこちらです。

techblog.lclco.com