Browser Appのパフォーマンスを継続的に計測したい
主に何をやりたいかというと、CPUやメモリについて継続的プロファイリングのようなことをやりたい。サーバーサイドで継続的プロファイリングをやっていたところ非常に便利だったので……
Reactで書かれたアプリのパフォーマンスを主として考えているが、特にそれに閉じずに汎用的に使えるように検討したい。
TL;DR
Excuse: 実際にはこれから実装・運用して試すので結論は変わると思う。あと試してないことが多いので変なことを書いているかも。
標準的な方法ではブラウザで完結してCPUの詳細な使用量を取ることは難しい (具体的な値が取得できない) ので ホストのメトリクス収集と併せて測定したほうが良さそうに思う。CPUプロファイルについては実験的なポジションながら実現できるようだ。これらの組み合わせでなんとかできると良さそう。
メモリについてはmeasureUserAgentSpecificMemoryを利用して使用量を取るのが良いか。ブラウザ (Chrome) のホストがコントロール下にあるというという状況限定ではあるものの、CDP接続でHeapProfilerをアタッチするといいうこともできそう。
いずれにせよ、正確なメトリクスを取るためにはホストマシンとの協調が必要であるという認識。
Chrome
DevToolsのPerformance
https://developer.chrome.com/docs/devtools/performance/reference?hl=ja
ページの描画が完全に完了するまでの諸々のパフォーマンスを計測できる
Memory API
https://developer.mozilla.org/ja/docs/Web/API/Performance/memory
performance.memory.usedJSHeapSize
performance.memory.totalJSHeapSize
performance.memory.jsHeapSizeLimit
標準からはdeprecatedなように見える
https://developer.mozilla.org/en-US/docs/Web/API/Performance/measureUserAgentSpecificMemory
これを使うという方法もあるようだが実験的ステータスではある
Compute Pressure API
https://developer.mozilla.org/en-US/docs/Web/API/Compute_Pressure_API
実験的ポジション
ref: https://asnokaze.hatenablog.com/entry/2022/12/26/004954
Compute Pressure APIを使うと、PCのCPU負荷が4段階で確認できます。
詳しいCPU情報はプライバシーの観点から公開しない設計になっています。
なるほど
HeapProfiler
ブラウザ (Chrome) のホストがコントロール下にあるという状況限定で利用ができる。
Chromeに対してCDPで接続してHeapProfilerをアタッチし、HeapProfiler.takeHeapSnapshot を定期実行することで .heapsnapshot を得られるので、これをどこかに蓄積しておいて何かあった時に調査するということができそう。
Datadog RUM
Datadogを使っているということもあり、これで一旦試してみる予定。エラートラッキングもできるので。
https://docs.datadoghq.com/ja/real_user_monitoring/application_monitoring/browser/
Long Tasks/LoAFをベースとしている
trackLongTasks: trueを設定すると自動的にLong Tasksを収集できる。
https://docs.datadoghq.com/ja/real_user_monitoring/application_monitoring/browser/monitoring_page_performance/
Browser Profiling
https://docs.datadoghq.com/ja/real_user_monitoring/correlate_with_other_telemetry/profiling/
プロファイル結果をLong Tasks/LoAFあるいはCPUメトリクス (なんらかの方法で頑張って取る) の向上と対照することで原因を調査しやすくなりそう
メモリ (ヒープ) の使用量についてはブラウザのAPIを利用して取得した値をCustom Metricsとして送付するのが良いようだ
一方、ホスト側のメモリのメトクスを取るというのが正確性が高そう
Sentry
https://docs.sentry.io/platforms/javascript/
余談: 継続的プロファイリング
JS Self-Profiling APIという実験的ステータスのAPIがあるらしい
https://developer.mozilla.org/en-US/docs/Web/API/JS_Self-Profiling_API
これにより継続的プロファイリングのようなことができる?
DatadogやSentryのBrowser Profilingはこれを利用しているようだ
余談: WebRTCのパフォーマンス測定
https://www.w3.org/TR/webrtc-stats/
RTCPeerConnection.getStats()
code:javascript
{
packetsLost: report.packetsLost,
packetsReceived: report.packetsReceived,
bytesReceived: report.bytesReceived,
framesDecoded: report.framesDecoded,
framesDropped: report.framesDropped,
jitter: report.jitter,
}