見出し画像

候補者管理ページのパフォーマンス改善 : 第一弾

はじめまして、HRクラウドの採用一括かんりくんdevopsチームです。
弊社からは初の技術記事になる予定で、公開に至れたことを嬉しく思います。
この記事では、弊社サービスのパフォーマンス改善事例を、解説を交えながら紹介していきます。

Core Web VitalsにLCPがあるように、Webサービスのユーザーエクスペリエンスを左右する重要な要素の一つがページのロード時間です。特に、大量のデータを扱う管理ページでは、この問題は顕著に現れます。本記事では、弊社で開発しているSaas :「採用一括かんりくん」の候補者管理ページで存在していたパフォーマンスの課題と、その改善に至ったプロセスについて詳しく説明します。
「採用一括かんりくん」の詳細についてはこちらをご覧ください。


課題

当初の候補者管理ページは、多くのデータが登録された負荷検証環境における読み込み速度の問題に直面していました。特に、フロントエンドの遅延が顕著で、リクエスト送信から完全なページの表示(Load)までの時間において、サーバーサイドとフロントエンドの間で処理時間が大きく異なることがわかりました。ある例では、その比率は1:5にも達していました。フロントエンドの処理時間をさらに分解すると、DOMContentLoadedまでとそこからLoadまでの時間がほぼ等しく分配されていました。また、このページのデータ転送量は28MBに及んでおり、これが全体のパフォーマンスに影響を与えていることが明らかでした。

分析

ボトルネックの分析を行ったところ、ドキュメントサイズ(特にhtml部分)が巨大であることが根本的な原因だと分かりました:

改善前 : 候補者管理ページのdocumentロード(負荷検証環境)

documentのサイズは約18MBと、レスポンス全体の転送量の過半数を占めています。Waterfallを見ると、その大半はContent Downloadが占めています。
一般的なwebアプリケーションでは、documentサイズは高々数百KB程度に収まるので、18MBという値は非常に大きいです。これは候補者管理ページが非常に多機能で、候補者に紐づくデータも数多くの種類があることに由来します。以下に示した候補者カードのUI例にそれが現れています:

候補者管理ページの候補者カードUI

他のサービス、例えばgithub.comにアクセスしてみると、筆者の環境でのdocumentサイズは70KB程度と、大きく異なります。
一方で、サイズは18MBと大きいものの、そのダウンロードに時間がかかるのは、現代のネットワーク環境からすれば一見不思議です(プロバイダーには一般的な光回線を使用しており、速度制限などを敷いた計測結果ではありません)。
これは、Progressive Renderingというブラウザの最適化技術が逆に仇となって招いたことであり、それを招いた原因がhtmlサイズの巨大さにあったとして説明できる現象であると考えています。Progressive Renderingについては、例えばこのサイトで詳しく説明されています。
Progressive Renderingによって、htmlは徐々にロード、レンダリングされる形ですが、scriptもまたjQueryを用いて多くの記述があるため、レンダリングごとにDOM操作やイベントリスナーの設定が大量に行われることになります。
すなわち、

  • Progressive Renderingによる反復的なレンダリング

  • レンダリングごとに行われる多くのJavaScript処理

の2点によって、documentのダウンロードに時間を要し、逐次発生するJavaScript処理が交互に次々と積み重なり、DOMContentLoadedやLoadのタイミングも大幅に遅延されてしまっていたと理解されます。

根本的な原因であるhtmlサイズの巨大さについては、htmlのほぼ全てをサーバーサイドレンダリング(SSR)していたことによるものだったので、フロントエンドにもフレームワークを導入して、一部はクライアントサイドレンダリング(CSR)されるようにすれば、改善が見込めるということが分かりました。

解決策

分析結果に基づき、主要なアプローチはhtmlの大部分に対してのCSRの導入としました。
他にも、アプリケーションの実装で様々な最適化を施しました:

  • サーバー側の最適化:

    • 重複処理の削減

    • 不要なHTMLエンコード処理の除去

  • フロントエンドの最適化:

    • 条件付きレンダーの導入

    • 重複していたJavaScript実行処理の削減

これらの詳細についてはここでは割愛します。

結果

これらの改善により、負荷検証環境ではページのロード時間とデータ量がそれぞれ1/10に短縮され、著しく改善されました。具体的には、DOMContentLoaded (DCL)までの時間とLoad (L)までの時間が大幅に削減されました。これは、ユーザーエクスペリエンスの向上に直結する結果です。

結論

このプロジェクトを通じて、ページのロード時間は1/10に短縮と、劇的に改善することができました。これは、適切な分析と戦略的な最適化のアプローチを通じて、どんなに大きなパフォーマンスの問題も克服できることを示しています。今後もこのような課題に取り組み、ユーザーエクスペリエンスの向上を図っていきたいと思います。

私たちのチームは、このプロジェクトを通じて得られた知見を社内のナレッジベースに蓄積し、今後も技術的な課題解決に役立てていく予定です。記事投稿などの取り組みによって、技術コミュニティ全体での知識共有を促進し、より良いWebエクスペリエンスの実現に貢献することを目指しています。

今後の展望

大きな改善は実現できたものの、完全な解決には至っていません。一般に、Core Web VitalsのLCPは、DCLとLの間に位置しますが、負荷検証環境におけるDOMContentLoadedまでの時間がLCPの推奨目標値に対してまだ長いことが課題として残っています。
ですが、今回のプロジェクトがリリースされたのは2023年夏頃で、その後も改善が続けられています。2024年4月時点(未リリースも含む)では、より高負荷な専用環境でのDOMContentLoaded時間が大幅に改善され、一般的な使用環境ではほぼ推奨値に達することが期待されています。残るボトルネックはほぼサーバー側にあり、この改善も目処が立っているため、目下でさらにプロジェクト進行中です。
こういった取り組みもリリースされ次第、技術記事として公開していく予定です。

ご覧いただきありがとうございました。