※この記事は、2024 Speee Advent Calendar9日目の記事です。昨日の記事はこちら tech.speee.jp
はじめまして、24卒で入社して不動産DXのHousii BUでエンジニアをしている山本です。
この記事では2024年10, 11月に行ったHousiiのページ表示速度改善についての話を書いていきたいと思います。Speeeで技術的なチャレンジができるか不安に思っている学生さんや、単純にページ表示速度を速くしたいというエンジニアの方に読んでいただけると嬉しいです。
- 1. そもそもHousiiはどのようなプロダクトか
- 2. 今回解決したかった問題
- 3. ページ表示速度を計測する
- 4. オーバーヘッドを解消する以外のアイデアを試す
- 5. オーバーヘッドを解消する
- 6. まとめ
1. そもそもHousiiはどのようなプロダクトか
まずそもそもHousiiがどのようなプロダクトなのかを説明したいと思います。Speeeと聞いてまず思い浮かぶプロダクトは何でしょうか?やはりイエウールなのではないかと思います。イエウールは家を売却したいユーザと不動産会社をマッチングさせるプラットフォームです。
それに対して、Housiiは家を購入したいユーザと不動産会社とマッチングさせるプラットフォームです。現在、家を購入するときによく使われるのは物件が大量に掲載されているポータルサイトですが、Housiiはポータルサイトと異なり、ユーザと不動産会社がチャットでやり取りすることによって、条件に合った物件を不動産会社に提案していただけるようになっています。
2. 今回解決したかった問題
Housiiにはチャット機能や物件閲覧機能が実装されていますが、他社のプロダクトと比較するとページが表示されるまでの時間が長く、ユーザが快適にページを閲覧できていないという問題がありました。そのため、今回はフロントエンドのページ表示速度を他社のプロダクト水準まで改善することにしました。なお、バックエンドのクエリ速度は以前に先輩が改善しており、そこが問題でないことはわかっていました。
3. ページ表示速度を計測する
パフォーマンスの問題を解決するときには「推測するな、計測せよ」ということがよく言われます。これはボトルネックを推測して解決したが、実際は別の場所がボトルネックで全体としては改善しなかったということを避けるために、計測によってどこがボトルネックなのかを明確にしてから改善せよということだと理解しています。そのため、まずページ表示速度を計測するところから始めました。
Housiiではバックエンドで発行されるクエリの速度は元々計測していましたが、フロントエンドのページ表示速度は計測していなかったため、まずそれを計測するための仕組みを導入する必要がありました。調査したところ、Sentry Performance MonitoringやDatadog RUMでページ表示速度を計測できることがわかりました。どちらも機能的には大差がなく、Sentryのほうが安価で計測できそうだったため、Sentryを導入することにしました。
4. オーバーヘッドを解消する以外のアイデアを試す
もしフロントエンドのページ表示にボトルネックがなかったとしても、それで諦めるのではなく、どうにか工夫して表示速度を早くする必要がありました。そのため、Sentryを使用した計測と並行して、以下のようなアイデアをチームで考え、それらを私がスパイクとして試しに実装してみていました。
- ページをローディングするときに表示しているローディングスピナーを削除する
- ページ表示前にデータをフェッチしておくことでページ表示を高速化する
- SSR (Server Side Rendering) を導入する
4-1. ローディングスピナーの削除
ローディングスピナーは一般的にページ表示を待つときに表示されるため、そこまでページ表示速度が遅くない場合でも、スピナーが表示されるだけでユーザとしてはページ表示速度が遅いと感じるのではないかという仮説がありました。
そこで、スピナーを削除しただけのものを作成して、チームのエンジニアやプロダクトマーケの方に見ていただいたところ、やはりスピナーを削除したほうが表示速度が速く感じるという人がほとんどでした。実装についてもスピナーを削除してレイアウトシフトを修正すれば良く、簡単にできるものだったため、こちらは採用することにしました。
4-2. データの事前フェッチによるページ表示の高速化
データの事前フェッチは、例えば一覧ページから詳細ページに遷移する場合に、詳細ページで必要な情報を一覧ページで事前に取得しておき、詳細ページに遷移するときはフェッチが走らないようにするということです。
これについても実装してみたところ、確かに詳細ページのページ表示は速くなりましたが、事前フェッチためのコードが必要でコードの複雑度が上がってしまうことがわかりました。そのため、こちらについてはページ表示のオーバーヘッドが存在しなかった場合に採用することにしました。
4-3. SSR (Server Side Rendering) の導入
Housiiは技術構成としてReact+Viteを採用しているため、Next.jsのように手軽にSSRを導入できるわけではありません。また、Housiiはほとんどのページがログインしないと閲覧できず、ユーザによって表示するコンテンツが変わるため、キャッシュを有効活用しづらいです。正直SSRについてはあまり深く調べられていないのですが、これらの理由から今回は採用しないことにしました。
5. オーバーヘッドを解消する
Sentry Performance Monitoringの導入から1週間ほど経ち、データが溜まってきたため、それらをいくつか確認したところ、以下の2つの問題があることがわかりました。そこで、これらを解決する方法を考え、実装を進めていきました。
- IDトークンを取得するための通信が毎回に走っている
- ログイン状態を取得するためのイベントリスナの発火が遅い
5-1. IDトークンを取得するための通信が毎回走っている
Housiiのバックエンドを叩くためにはアクセストークンが必要です。このアクセストークンを取得するためには、Firebase AuthenticationライブラリのgetIdTokenを使用します。この関数の第二引数はトークンを強制的に更新するかどうかのフラグを渡すようになっているのですが、これが常に true
になっていたため、通信が毎回走っていました。この通信がページ表示のオーバーヘッドになっていました。
フラグを false
にすれば、有効期限が切れている、もしくは5分以内で有効期限が切れる場合だけ通信が走るようになるため、常に false
を渡すようにしたいです。ただ、ユーザのメールアドレスが有効であるかを検証した後だけは、IDトークンを強制的に更新しないとエラーが発生してしまうということがわかりました。そのため、その場合だけ true
を、それ以外の場合は false
を渡すように変更することで、この問題は解決しました。
5-2. ログイン状態を取得するためのイベントリスナの発火が遅い
Housiiのバックエンドを叩くにはアクセストークンが必要なため、ユーザがログインしている必要があります。Firebase Authenticationライブラリでログイン状態を取得するには、onAuthStateChangedというイベントリスナの発火を待つ必要があります。しかし、このイベントリスナはFirebaseのユーザ取得APIのレスポンスを待っており、これもページ表示のオーバーヘッドになっていました。そこでアプリケーション側で工夫することでこのオーバーヘッドを隠蔽することにしました。
Firebase Authenticationライブラリは、ユーザがログインしている場合はそのユーザの情報をブラウザのIndexedDBに保存しています。そのため、その情報をアプリケーション側で読み出し、それをキャッシュとして使用すれば、Firebaseのユーザ取得APIの完了を待たなくてもログイン状態を取得できて、Housiiのバックエンドを叩くまでの時間を短縮できます。フローチャートにすると以下のようになります。赤くハイライトされているところが今回実装した部分です。これを実装することで、この問題も解決しました。
6. まとめ
このようにローディングスピナーの削除とFirebase周りの改善をすることで、Housiiのページ表示速度を改善できました。その結果、ユーザがより快適にページを閲覧できるようになったと考えています。
だいぶ技術寄りの記事になったと思うので、この記事を読んでSpeeeでも技術的なチャレンジができるんだと感じていただけると嬉しいです。ただ、前提として今回のページ表示速度改善をやる目的として、ユーザが快適にページを閲覧できるようにするというユーザ目線の目的があることは強調しておきたいです。
Speeeのエンジニアがやりたいことは技術を使って、ユーザの課題を解決することだと思っています。今の時代はChatGPTのようなAIが出てきたこともあり、技術力を向上させるだけでなく、事業的な目線を身につけることも重要だと思います。技術的なチャレンジをしつつ、事業的な目線を持つことにも興味のある方はぜひSpeeeに来ていただければと思います。
Speeeでは一緒にサービス開発を推進してくれる仲間を大募集しています!
新卒の方はこちらより本選考に申し込みが可能です!
キャリア採用の方はこちらのFormよりカジュアル面談も気軽にお申し込みいただけます!
Speeeでは様々なポジションで募集中なので「どんなポジションがあるの?」と気になってくれてた方は、こちらチェックしてみてください!もちろんオープンポジション的に上記に限らず積極採用中です!!!