Retty Advent Calendar 2022 Part1の9日目です。
はじめに
Webチームの木本です。
パフォーマンスを意識した開発は皆さんしていますでしょうか?施策をリリースしたところ、それによってWebパフォーマンスがガクッと下がっているのに誰も気づかないのは怖いですよね。「気づいたらパフォーマンスが落ちていた」ということはよく聞く話です。
そのために重要なのはWebパフォーマンス定期観測を行うことです。今回、Webパフォーマンス定期観測を簡易的に行うシステムを構築しました。このシステム構築のために行った技術選定について紹介します。
技術選定
Webパフォーマンスを測定するにあたり、考慮すべきことは以下になります。
- フィールドデータかラボデータか
- 計測ツール
- 計測するタイミング
- 計測結果の保存とUI表示を行うシステム
フィールドデータ/ラボデータ
簡単に言うと以下のような違いになります。
フィールドデータ
- 実際のユーザーの環境で測定した結果
- これを測定するためには、ユーザーはJSを読み込みパフォーマンスを測定して送信することになる
ラボデータ
- シミュレーション環境でWebパフォーマンスを測定した結果
- 特定のタイミングで、ユーザーのブラウザ環境を模したシミュレーターでページにアクセスし、パフォーマンスを測定する
Googleが提供しているWebパフォーマンス計測ツールにPageSpeed Insightsというものがあります。この計測結果の「実際のユーザーの環境で評価する」はフィールドデータで、「パフォーマンスの問題を診断する」で見ている部分はラボデータになります。
またSearch Consoleのウェブに関する主な指標欄もフィールドデータです。
フィールドデータという実際のユーザーさんがどれだけのパフォーマンスでページを見てもらえているのかを確認するのは重要ですが、今回のWebパフォーマンス観測システムではフィールドデータではなくラボデータを見ることとしました。
理由としてはフィールドデータはユーザーの環境にも左右される指標なため分析が難しいほか、ページにJSを挟んで余計にパフォーマンスが悪化することは避けたかったためです。
また、技術的な準備をしなくてもSearch ConsoleやChrome UX Reportでパフォーマンスを見ることはできます。ユーザーの環境でのパフォーマンスをより緻密に観測したい場合は副次的な観測結果としてフィールドデータを使うことも検討した方が良いでしょう。
計測ツール
ラボデータを計測できるツールは、無料で使える範囲では以下の2つが有力と思います。
- Lighthouse
- Googleが提供する計測ツール。パフォーマンスの他アクセシビリティなどもチェックできる
- Google Chrome用の拡張機能として導入することができるほか、Node.jsから動かすこともできる
- 取れるデータは(WebPageTestに比べれば)少ない
- Largest Contentful Paintなどの数値中心で、Waterfall図を取ることはできない
- 前述のPageSpeed Insightsは内部でこのLighthouseを利用している
- 検索エンジン大手が見ている指標が取れるため、SEO目的のWebパフォーマンス改善を行う際は監視したい
WebPageTestのWaterfall図などによる分析は非常に魅力的で、それらの詳細なデータを保存しておきたいという気持ちはあったのですが……今回はLighthouseを採用することにしました。
理由はWebPageTestのローカル実行にDockerが必要など重い準備が必要だったためです。GitHub ActionsやCIでミニマムにやりたかったため、それを準備し保守していくのは大変だと判断しました。
しかし、ECSなどでコンテナを動かしてでもいいから腰を据えて観測したいというような場合はWebPageTestを採用しても良いと思われます。もしくはそもそもWebPageTestの有料版を利用するなどの選択肢があります。WebPageTestではLighthouseの結果も取得可能なので、Lighthouseの上位互換として利用することも可能です。
Lighthouseで測れる指標
Lighthouseでは様々な指標が測れますが、SEO上重要とされているのはCore Web Vitalsと呼ばれる3指標です。こちらの指標が一定を超えると、GoogleのSearch Consoleにも警告が発出されるようになります。
- Largest Contentful Paint(LCP)
- 一番重要な画像・テキスト要素(ここが少し曖昧ですが)が読み込まれるまでの時間です
- RettyではWebパフォーマンス改善の文脈ではこれを一番重要視しています
- First Input Delay(FID)
- ユーザーが最初に操作した時に、実際にイベントハンドラが動き出すまでの時間です
- Lighthouseで測れる指標はMax Potential First Input Delayと呼ばれる最悪のケースの値です
- あまり使わないかも……
- Cumulative Layout Shift(CLS)
- 最初の描画から、要素が出現したり要素の大きさが変わったりすることでレイアウトがずり下がる量です
他にも観測すべき指標として
- Total Blocking Time(TBT)
- メインスレッドがブロックされた時間
- First Contentful Paint(FCP)
- 最初にコンテンツが表示された時間
などを指標として測ることができます。
計測タイミング・計測環境
計測タイミングにも方法が2つあります。
CI実行時に計測する方法
- lighthouse-ciで実現している方法
- CI実行時に計測を走らせることができるシステム
- どのコミットが問題となってWebパフォーマンス低下を招いたかを把握できるようになるメリットがある
定期観測
- 時間を空ける定期的に観測する
- 急激に悪化したタイミングから、リリースログを追って原因リリースを突き止める形になる
コミットごとにLighthouseの結果を蓄積できるlighthouse-ciの仕組みは魅力的です。どこのコミットでパフォーマンスが悪化したのかがひと目でわかるので、問題の切り分けもしやすいでしょう。しかし、今回はlighthouse-ciではなくシンプルな定期観測にしました。
というのもRettyのアーキテクチャはコードベースが複数のリポジトリに分かれているため、lighthouse-ciのようにコミットごとに計測する仕組みが非現実的だったためです。
ただ、定期観測ではリリースを突き止めるのが若干大変となります。アーキテクチャが刷新され、リリース数も増えた場合はlighthouse-ciのようなCI実行時に計測する仕組みを取り入れることも考えていくべきでしょう。
また、計測環境はGitHub Actionsとし、cronトリガーを使うことで定期的な実行を行うこととしました。GitHub Actionsでは厳密な計測環境としてはやや不向きかと思いましたが、lighthouse-ciでよく使われている環境なため許容できると判断しました。
計測結果の保存とUI表示
計測結果の保存とUI表示はWebパフォーマンスの変化を追うのに重要です。
調べてみると独自UIを使っているケースや、スプレッドシートで管理しているケースもありました。
しかし、今回は既に利用しているDatadogをそのまま利用し、カスタムメトリクスとして送ることとしました。Datadogでは様々なスコアを集計しダッシュボードに表示させたり、しきい値を越したらアラートを出すことが比較的簡単にできます。そのため、その後のUI構築も簡単という理由で、カスタムメトリクスを利用することにしました。DatadogではカスタムメトリクスはFreeプランでは利用できませんが、Pro以上のプランではカスタムメトリクスを利用することができます。
技術選定まとめ
今回は以下の通りの技術選定としました。
- Lighthouseで測定
- WebPagetestを利用するという案もあったが、Dockerを使うなどかなり大掛かりな実行環境が必要なのでLighthouseでの測定とした
- Datadogでデータ保存・UI
- RettyではDatadogが使われており、ある程度基盤があったのでそのまま利用
- ダッシュボード構築やアラート構築なども簡単にできる
- GitHub Actionsで実行
- Node.jsで実行するため、軽量なGitHub Actionsでトライした
- 演算能力が前後してブレが出るかな?と思ったが、lighthouse-ciなどでも使われているので許容範囲内と判断。
実装
実際にLighthouseで測定し、Datadogに送るシステムを作りました。 (なお、実際にRettyで運用しているシステムをブログ用に簡易化させたものになりますのでコードベースはかなり違います)
環境・ライブラリ
- Node.js
- Lighthouse及びDatadogとの連携を実現するため、以下のnpmライブラリをインストールする
- lighthouse
- Lighthouseの公式実装
- chrome-launcher
- @datadog/datadog-api-client
- Datadog謹製のNode.js用Datadogクライアント
- Datadogについては色々なライブラリがあり迷ってしまいますが、今回のケースであれば@datadog/datadog-api-clientで十分対応可能でした。
- lighthouse
実装した結果はこちらです。なお、本テックブログのため若干省いた部分があります。
Datadog以外にもBigQueryに入れることや、Lighthouseだけでなく別のツールで観測すること、あるいはデータベースを直接叩いてランダムなお店ページを出して計測するということを将来的に可能にするため、Clean Architectureで実装しました。
まとめ
Webパフォーマンス観測をする際の技術選定の流れについて解説しました。
Webパフォーマンス観測はデータがあればあるほど良いし、ユーザーさんに近いデータがあれば良いと思ってしまいます。しかし実際はそれはなかなかコスト面やアーキテクチャ面でも厳しく断念せざるを得ないこともありますが、様々な制約に対応しながらミニマムに始めることができます。
Webパフォーマンス観測をすることで初めて自分の立ち位置を知ることができ、パフォーマンスの悪化を防いで向上へ向けていくことができます。ミニマムに始められますので、少しずつ定点観測の範囲を広げてみてはいかがでしょうか。