社内会議室予約システムのパフォーマンス改善してみた

この記事は[リクルート ICT統括室 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/recruit-ict "リクルート ICT統括室 Advent Calendar 2023") 6日目の記事です。

ICT統括室の@s__taiです。
元々はカスタマー向けサイトの開発をメインに行っていましたが、リクルートに入社してからは社内向けWEBプロダクトを中心に企画、構築、改善を行っています。
今回は、全社に向けて提供している社内会議室予約システムのパフォーマンス改善を実施した内容について書いてみます。

## 背景
リクルートの社内システムや提供ツールは、半期に一度、全従業員からシステム満足度のフィードバックをもらう機会があります。
その中で社内会議室予約システムに対して「遅い！！」といった声が多く寄せられたことがわかりました。
このフィードバックを受け、改善を検討することにしました。

社内会議室予約システムは、当社の会議室や、オンライン会議用のブースなど（数十拠点、会議室1,000部屋以上）の利用状況を一覧で表示できて、それに対して予約したり、予約変更したりできるWebシステムとなっています。

イメージとしては、会議室の予約が表示されているカレンダーアプリのようなものを想像すると分かりやすいかと思います。

## 大まかなシステム構成
このシステムは保守を別の部署が担当しており、今回の改善施策については私たちが対応することになったので、まずは担当部署から現状やシステム構成についてヒアリングすることから着手しました。
ヒアリングの結果、ざっくり以下のようなシステム構成であることが分かりました。

- フロントエンドはReact.js（+Flow）を利用しており、SSGで配信している。
- バックエンドはNode.jsで作られたAPIをNginxを経由して配信している。
    - APM（アプリケーション性能管理ツール）は導入されていない。
- インフラはAWS上にALB、EC2、Aurora MySQL等で構築されている。
    - Aurora MySQLのオートスケーリングは設定されている。

![スクリーンショット 2023-11-24 1.05.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629890/7ff3ff99-f1ba-5ffb-026b-f3679e52e4dc.png)

## 現状課題の特定

パフォーマンス改善を行うにあたり、まずは、何がボトルネックになっているのか、どこを改善すれば1番効果的にユーザー満足度を上げられるのかを把握する必要がありました。
しかし、APM等は導入されておらず、またAPMを導入するには調整やリリース等、時間がかかりそうなことが分かり、APMの利用は諦めざるを得ませんでした。
そこで、取っ掛かりとして Chrome Developer Tools から実行できる Lighthouse を使ってアプリケーションの品質をチェックしてみることにしました。

Lighthouse ではアクセシビリティやSEOなどを含めたWebアプリの全体のパフォーマンス、品質の診断を数十秒程度で行えます。
今回は、社内向けWebアプリとなるため、SEO向けの項目は不要ですが、Lighthouse の結果をベースに、Chrome Developer Tools の Network や Performance タブを利用し改善箇所の勘所を把握する事にしました。

実際の改善前の Lighthouse の結果は以下のようなものでした。

![スクリーンショット 2023-11-23 15.33.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629890/fe7313f7-b623-64f8-e182-bd2a3e7939ab.png)
![スクリーンショット 2023-11-23 15.31.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629890/767fa07d-da41-cad1-ca30-e1d2712cb93f.png)
![スクリーンショット 2023-11-23 15.37.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629890/97ee4d16-fc4b-a6b9-d2b1-a142ebd2667e.png)
この結果から、大まかに以下の課題があることがわかりました。
- フロントエンドでDOMが大量に生成されており、その生成に時間がかかっている。
- APIの転送量が多く体感スピードが遅くなっている。（APIレスポンスが圧縮されてない）
- APIレスポンスがそもそも遅い。

## 改善の方針
ここまでの調査結果から、改善の方針を以下のように決定しました。
- 1秒程度でレンダリングを完了できるようにする。
    - ただし、改修のコスパを考え、アクセスが多いページを主な対象とし、アクセスが少ないページや特殊な条件での検索時などはそれ以上かかっていても許容する。
- フロントエンドでのDOMの生成を減らし、レンダリングコストを抑える。
- APIレスポンスを圧縮し、APIの転送量を減らす。
- APIレスポンスのスピードを改善する。
    - DBもネックになりやすいので追加で Auroa MySQL の Performance Insights の設定を行い、DB側の状況もウォッチできるように設定する。

## DOM生成の削減
現状のシステムでは、表示対象の会議室の一日の予約状況が全て一気にレンダリングされていました。
例えば、本社ビルの会議室（約600部屋）を対象にして表示をさせた場合、それらの全ての予約状況が初期表示時にレンダリングされることになってしまい、画面表示までに8秒以上かかっている状況でした。
そもそも、上記の様な部屋数は初期画面には収まりきらないことから、最初から全てレンダリングをする必要はないのでは、と考えました。そこで、仮想スクロールを利用することで、画面上に表示できる部屋数＋スクロールバッファの分だけレンダリングを行い、DOM生成を最低限にするように改善を行いました。
仮想スクロールにはコミュニティが活発であるという理由から、TanStack Virtual を採用することにしましたが、その作業の中で、Reactのバージョンが古くてライブラリが使えない事が発覚。
そこで、React のバージョンアップを行い、プラスで flow から TypeScript へと言語を変更し、保守性を高め、将来的なエンハンスも行いやすいように対応を行いました。

## APIレスポンスの圧縮
こちらは、Nginxでコンテンツ圧縮を行う設定を追加しサクッと対応を行いました。
そもそも何故設定されていなかったのか（し忘れた？）謎ですが、長く利用しているシステムを見直すと、思わぬ課題ってけっこうありますよね。今回の改善で判明し対応できたので良かったです。

## APIレスポンスのスピード改善
APIレスポンスのスピードについては、最初はDBへ重いクエリが流れていないかを疑っていたのですが、Performance Insights の結果からアプリ側の問題と分かりました。
調査の結果、SQLの実行速度自体は早かったものの、取得レコード数が異常に多く、その結果をレスポンスするまでに時間がかかっていました。
DBからの取得レコードが多い理由を深掘りしていった結果、一覧のレンダリングには不要な処理が含まれており、かつ、APIの設計が最適ではなく、無駄なクエリ、レスポンスまで生成していました。
そのため、APIを分離し、必要な箇所で必要な情報のみを参照できるように改修を行うことで、APIレスポンスのスピードを改善しました。

## 改善結果
上記の施策を行った結果、以下の状態まで改善することができました。

![スクリーンショット 2023-11-23 16.17.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629890/a8b504a8-56fd-36ac-d4cb-a0b61c16f1b0.png)
当初、一覧のレンダリング完了まで約8秒程度かかっていましたが、改善により1秒程度まで短縮することができました。

## まとめ
今回の事例では Lighthouse のアドバイスを参考にできたため、調査工数を大幅に削減し稼働工数としては1人月程度で完了できました。Lighthouse は気軽に計測できるので、遅いな？と思ったページに対して利用してみることをおすすめします。

- Lighthouse の改善項目を見る事で改善が必要な項目はある程度わかる
  - 構築や改修フェーズでも、Lighthouse は意識した方がよい
- Lighthouse は実行する人の環境に一部依存するので厳密性は低い部分がある

今まではユーザーインターフェース（UI）のモニタリングが不十分でしたが、このリリースを機会に、Microsoft Clarity というツールも導入しました。
これにより、ユーザーの行動をより詳細に分析できるようになり、今後はUIの改善にも力を入れていく予定です。

[リクルート ICT統括室 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/recruit-ict "リクルート ICT統括室 Advent Calendar 2023")では、リクルートの社内ICTに関する記事を投稿していく予定です。もし興味があれば、ぜひ他の記事もあわせてご参照ください。