本記事は、一休.com Advent Calendarの23日目です。
宿泊事業本部フロントエンドエンジニアの宇都宮です。
先日(12/19)、一休の宿泊予約サービス(以下、一休.com)のスマホ版の予約入力画面リニューアルをリニューアルしました。本記事では、
- どのような方針で
- どのような技術を使って
- どのような設計で
- どのように実装していったか
を紹介します。
Before/After
リニューアル前
ファーストビュー
エラー通知
次の画面へ進む前に、alert()
リニューアル後
ファーストビュー
エラー通知
項目の上に表示&自動フォーカス
主な変更点
- デザインの刷新
- エラー通知の改善
- クレジットカード入力画面、オプション注文画面の統合
実装面では、ASP.Net Web Formsのユーザーコントロールを大幅に削り、Vue.jsのコンポーネントに置き換えました。
以前の画面の課題
リニューアル前の予約入力画面には、いくつかの課題がありました。
- UIが使いにくい 特にエラー通知が不親切
- 画面の表示が遅い(サーバサイドで大量のデータを読み込んでいるため)
- ユーザーコントロールの変更が難しく、生産性が低い
エンジニアの観点からすると、特に生産性の低さが気になっていました。ユーザーコントロールとはASP.Net Web Formsフレームワークの機能で、再利用可能なコンポーネントを定義する機能です。
ユーザーコントロールは、上手に活用すれば生産性を向上させる機能だと思いますが、残念ながら一休の予約入力画面では、生産性を低下させる原因となっていました。というのも、数千行規模のユーザーコントロールが複数存在し、それぞれが密結合していたのです。
4月に、フォームの入力欄の順番を入れ替える作業を行いました。表面上は簡単な調整で、普通のHTMLなら30分でできそうな作業でしたが、実装1日+テスト0.5日という工数を費やす必要がありました。
あるユーザーコントロールから別のユーザーコントロールに入力欄を移動するには、その入力欄のために定義されているフィールド/プロパティやメソッドを、まるごと別のユーザーコントロールに移す必要があったためです。
↓は当時のプルリクのスクリーンショットですが、3項目の移動で+3,571 −166という大きなdiffが生じています。
また、予約入力画面のaspxファイルは単体で5,000行(※)ほどあり、ファイル内で行きつ戻りつするのも非常に大変でした。
※:JSが3,000行、残りはHTMLとASP.Netのコードナゲット
このような理由から、予約入力画面のリニューアルを検討しました。
リニューアルの方針と実装
スコープ
予約の画面は膨大な業務ロジックに支えられているため、実装工数が膨らむことは避けられません。そこで、以下のようにスコープを限定して進めました。
- 対象はスマホ版の予約入力画面のみ
- PC版や、スマホ版でも予約確認画面や完了画面には手をつけない
- サーバサイドの業務ロジックにはできるだけ手をつけない。レスポンス速度の改善はスコープ外
技術選定
予約入力画面のリニューアルでは、EFO(Entry Form Optimization)の観点から、JavaScriptでリッチなエラー通知を行うことを目指しました。あわせて、開発者の生産性を向上させる必要性も感じていました。そこで、JavaScriptフレームワークのVue.jsを導入しました。
既存の画面で使用しているjQueryではなく、Vue.jsをメインに据えた理由は、生産性が大きな要因です。Vue.jsの単一ファイルコンポーネントを使用すると、画面上の要素(コンポーネント)ごとに、関連するロジック(js)とスタイル(css)をひとまとめにすることができます。コンポーネントを小さく保ちながら実装を行えば、コードのメンテナンス性を大きく向上させることができると考えました。
実装
Vue.js + Vuex + VeeValidateというスタックで実装を行いました。
Vuexを導入するかは迷いましたが、予約入力画面で使用する膨大なデータを一元管理できるのは大きなメリットでした。VeeValidateはpluggableな構成になっていて、独自のバリデーションを簡単に定義できるようになっているのが良かったです。
テストには vue-test-utils を使用しています。Vueコンポーネントのテストは一部のメソッドと算出プロパティだけで、レンダリングのテストは行っていません。
現在のところ、コンポーネントの構成は以下のようになっています。
大枠から作っていって、徐々にコンポーネントを分割していくという方針を採ったため、コンポーネントの粒度は大きめです。また、本来はコンポーネントにすべきなのに、コンポーネント化できていない部分もあったりします(たとえば、お知らせメール受信設定)。
目安として、.vueファイルが100行を超えたらコンポーネントを分割できないか検討するようにしていました。最も大きなコンポーネントで.vue 200行 + .js 300行ほど、平均的なコンポーネントのサイズは100行程度に抑えることができたため、コードの見通しはかなり良くなりました。
また、以前は5,000行ほどあった予約入力画面のaspxファイルは、リニューアルによって200行にまでスリム化しました。
残る課題
本ページのリニューアルに関しては一区切りというステータスですが、以下のような課題が残っていると認識しています。
- 一休.com全体でのデザイントーンがバラバラ
- 画面の表示は相変わらず遅い
- コンポーネントの粒度はもう少し細かい方がよさそう
- JavaScriptの単体テストが不足している
- CSS Modulesがまだ使いこなせてない
デザイン面の課題はデザイナーと協力して、プログラムの課題は他のエンジニアとも認識を合わせながら、引き続き改善していきたいと考えています。
明日はzimathonさんの「開発組織の目的型組織への移行」です。