フロントエンドのモダン化の。その前に。
最初に
以前フロントエンドのリプレイスに、いつまでかけるんだ?の中で、レガシーなフロントエンドをモダン化する際にどれぐらい時間がかかるのかを分析しました。そしてインターネットで公開されている情報を見る限り、複数年の大掛かりなプロジェクトになることが多いという感想を残しました。
複数年の大掛かりなプロジェクトならば、課題をしっかり評価して、最悪の事態を避け、リスク管理を行うことが当然です。そこでリスク評価の一助として、私の知る限りで、リスクになりうるポイントとリスクを軽減する方法を紹介したいと思います。
なお、本記事は百ページ以下の小規模アプリを対象としていません。数百ページ以上の中規模から大規模アプリの話になりますのでご了承ください。
モダン化のリスク
ほぼ確実に中断されます
フロントエンドのモダン化プロジェクト自体は機能を追加しません。したがって機能が増えないプロジェクトに開発リソースを何年も投入することになります。
当然ビジネス側からクレームが来ます。「開発は一体何をやっているんだ?」という疑問と不信感です。開発リソースをモダン化プロジェクトから剥がし、機能追加に回すようにプレッシャーがかかります。
つまりモダン化プロジェクトが中断されるリスクは極めて高いです。むしろプロジェクト当初から中断の可能性を見越して、中断されても価値が生まれるように計画した方が良いでしょう。
組織としては無事ではいられません
フロントエンドのモダン化に複数年をかけているうちに、ビジネスと開発の信頼関係が揺らぐ可能性があります。ビジネスは新機能開発を優先したいのに、開発側はこれを断り、モダン化を優先することも多いでしょう。「開発は一体何をやっているんだ?」「開発は非協力的だ!」「開発はビジネスことを考えていない!」という疑問と不信感が生まれます。
またプロジェクトが中断すると、エンジニアのモチベーション維持に苦労するケースも出てきます。モダン化を期待して入社したのに、レガシーjQueryをメンテナンスする業務を依頼されたら、エンジニアには話が違うと思うでしょう。離職リスクにつながります。
最悪のシナリオとして、モダン化プロジェクトに端を発して開発組織が崩壊に近い状態になることもあります。これは決して大袈裟に言っているわけではありません。これぐらいの覚悟を持ってモダン化プロジェクトに取り掛かる必要があるということです。
デザインがバラバラになってしまうリスク
複数年の長期プロジェクトになると、PMは「ついでに」デザインを変更したり、機能を追加したりしたいという誘惑に駆られます。ビジネス側を説得する際、デザインや機能の変更をプロジェクトにバンドルしないとなかなか納得してくれないためです。
これは大きな悲劇を生む可能性があります。
上述したように、モダン化プロジェクトは途中で中断してしまう確率が高いです。モダン化プロジェクトにデザイン変更を含めてしまうと、中断した時点でページによってUI/UXバラバラのデザインになってしまいます。
UI/UXがバラバラなことをお客様が見過ごすはずはありません。UI/UXがバラバラなら、お客様は内部品質も悪いだろうと推測します。競合営業としては願ったり叶ったりの急所なので、営業トークの中で必ず取り上げるでしょう。UI/UXがバラバラな状態がビジネスへのインパクトがないはずがありません。
オアシスの砂漠を横断しようとして、途中で止まっているような状態です。そこは死地です。すぐに渡り切るか、出発地に戻るしかありません。
中断してしまう可能性を事前にしっかり理解し、リスクを自覚し、デザイン変更や機能追加要望の受け入れを最小化するべきです。新デザインを承諾するにしても、旧デザインとの差を最小化し、仮に中断してしまっても違和感を減らすように心がけるべきでしょう。
メンテナンスコストが上がってしまうリスク
モダン化プロジェクトが中断すると、機能やデザイン(CSS)を二重にメンテナンスすることになります。例えばモダンUI用のデータピッカーとレガシーUI用のデートピッカーを二重に持つ必要があります。またデザインを完全に揃えている場合であっても、モダンUI用のCSSモジュールとレガシーUI用のSASSファイルなどを二重に持つことになるでしょう。
モダン化プロジェクトの中断により大幅にメンテナンスコストが増えます。
モダン化したUI/UXの評判が悪いリスク
モダン化と同時にUI/UXを大きく変更すると、顧客からの評判が悪くなる可能性が高いです。単純に慣れの問題なら数ヶ月で問題は消えますが、ずっと文句を言われ続ける可能性もあります。
大事なことは、モダン化してもUI/UXが良くなるとは限らないことです。UI/UX向上はあくまでもプロダクトマネージャーやUXデザイナーがどれだけ顧客のニーズを理解し、適切な解決策を導入するかで決まります。これが不十分であれば苦情が入り、開発メンバーはこの対応に追われます。
モダン化したのにUI/UXのクレームが入る可能性は高いので、プロジェクトが中断する可能性はさらに高くなります。
簡単なページから先にやるのはリスク
大プロジェクトの場合、どのページから先に取り掛かるかという問題が発生します。優先順位の問題です。
フロントエンドのモダン化は顧客の声やビジネスニーズとは直接関係ないことが多いため、優先順位の決め方がアバウトになりがちです。そして多くの場合、簡単なページから先にやるという方針になります。しかし簡単なページからやるとリスクを拡大させてしまう可能性があります。
- 簡単なページはそもそもモダン化のUI/UX上のメリットがほぼないページです。インタラクティビティがないので、React/Vueのメリットがないものが多いです。メリットが見せられないので、ビジネスが納得しない可能性が高くなります
- 簡単なページをいくらモダン化しても、完了時期の見通しは得られません。いつまで経っても難しいページのモダン化にかかる工数が見積もれないからです
プロジェクトのリスクを軽減したいのなら、中断のリスクを減らしたいのなら、簡単なページから先にやるべきではありません。難しいページ、もしくはポジティブインパクトのあるページから先に取り掛かる必要があります。
リスクを減らす方法
リスクを減らすには、工数を最小化するしかありません。
フロントエンドのモダン化はそもそもビジネスインパクトがほとんどありません。無理にデザイン変更や機能追加でインパクトを増やそうとしてしまうと、さらに泥沼にハマるだけです。
早く死地を抜けられるように、最初から工数を最小化することが最善の方法と言えそうです。ここでは大幅に工数を減らす方法を紹介します。
SPAを諦める
ここではSPAの厳密な定義に拘らず、以下のように定義します。
- SPA: JSON APIエンドポイントからデータを取得し、ページ全体をモダン技術でレンダリングするもの。便宜的にNext.js SSRもここに含めて話をします。
- 埋め込み: レガシー技術でHTMLにレンダリングされたページ(例えばERB)の中に、モダン技術で作成されたコンポーネントを埋め込むもの
下記の理由によりSPAと比べて埋め込みの方が工数が大幅に減ります。工数を減らすためにSPAを諦めるのは極めて有効な選択肢です。
- 埋め込みの場合は既存のcontroller (ERB表示用のもの)もview templateもほぼそのまま再利用します。埋め込むコンポーネントに渡すpropsだけJSON化し、埋め込み箇所に書き込みます
-
SPAの場合はJSON APIエンドポイントを新規に用意することが多いでしょう。例えば
controllers/api/v1/*_controller.rbのようなものです - SPAの場合のJSON APIエンドポイントには、リアクティブでない箇所のデータもJSON化します。多くのページはむしろリアクティブではない箇所の方が多いので、かなり無駄が発生します
- 埋め込みの場合のcontrollerはページ単位のものになります。それに対してSPAではしばしばリソース単位のエンドポイントを設計します。権限によってフィールドの出し分けが発生することもあるので、controllerの設計は既存のものと変わってきます
- SPAの場合はブラウザ側のコードが複雑化します。ローディングステート、fetchしたデータを保持するステートを用意し、fetch処理とエラーハンドリングの追加が必要になるからです
SPAの場合はページ単位のJSON APIにする
仮にSPAを採用する場合でも、controller設計を維持し、ページ単位のJSON APIにした方が工数は減らせます。リソース単位のAPI設計にしないということです。
- リソース単位のAPI設計の場合はcontroller数が単純に増えます。また認証・認可の処理が変わり得ます。一方でページ単位のJSON APIなら既存のcontroller (ERB表示用のもの)をそのまま使えます
- リソース単位のAPIの場合、ブラウザは複数のJSON APIを叩かないとページが表示できなくなります。このため、ステート管理やエラー処理等が複雑になってきます
例えばNext.js Pages RouterのgetServerSideProps()関数の返り値はそのままJSONとしてブラウザに渡されますが、これはページ単位のJSON APIの例です。Remixのloaderが送信するのも同様です。また最近人気のあるInertia.jsもこのようなJSONをブラウザに送信します。このようにページ単位のJSON APIを使うことは、ステート管理を簡略化した最新のReactフレームワークでは一般的なやり方になってきています。
デザイン変更・機能変更は避ける
デザイン変更・機能変更をすれば工数が増え、プロジェクトが中断する可能性が高まります。また中断した場合のネガティブインパクト(UXもDXも)が多くなります。
これを避けるためにはデザイン変更・機能変更とモダン化は別に対応するべきです。モダン化の前にデザイン変更をしても良いし、後にしても良いかもしれません。また変更後のデザインを工夫し、レガシーUIと並べても違和感がないように色調などを似せることも有効でしょう。
色々アイデアはあると思います。プロジェクトが中断しても違和感がなく、バラバラ感が生じないことを重視しなければなりません。
ページ単位ではなくコンポーネント単位でモダン化
ページ単位ではなくコンポーネント単位でモダン化するのが良いでしょう。これについては食べログの考え方に沿うのが良さそうです。
コンポーネント単位のモダン化に徹することにより、モダン化工数を大幅に削減でき、かつ中断した場合のメンテナンス工数も大幅削減ができます。
- モダンUIコンポーネント以外の箇所はレガシーUIのcontrollerおよびview template (例えばERB)をそのまま使えます
- モダンUIコンポーネントの大きさを最小化できます。モダンUIコンポーネント作成の工数を削減し、propsとしてJSON形式で渡すデータも最小化できます
- コンポーネントの二重管理が避けられます。レガシーUIコンポーネントを全て一気にモダンUIに切り替えられるので、2種類のコンポーネントを管理する必要がありません
- 不必要なモダン化を避けられます。モダンUIコンポーネントのメリット(少なくとも名目的には)はインタラクティブなUI/UXの実現ですので、インタラクティブではない画面要素をモダン化する必要はありません。これを迂回できるため、大幅な工数削減になります
戦略的に優先順位を考える
なんとなく優先順位を考えるのではなく、ビジネスに対する説明がしやすいように戦略的に作業の優先順位を考えるべきでしょう。ビジネスインパクトが大きい箇所を早めにやって、モダン化の必要性を理解してもらうべきでしょう。
ケースバイケースで異なると思いますが、ビジネス的理由で中断されにくいように、戦略的に優先順番を考える必要があります。
追記:ビデオ
この記事で書ききれなかったことをダラダラとビデオで語りました
Discussion