Article by: Abdelrahman Awad(読了時間:6分)
bfcacheMetricsIntegrationは、3つのbfcacheシグナルをアプリケーションメトリクスとしてモデル化します。このインテグレーションはオプトイン方式で、JavaScript SDKs v11でリリースされました。Webを使う人なら誰もが感覚的に知っている瞬間があります。リンクをクリックしてページを読み、「戻る」を押すと、前の画面がすぐそこにあります。スピナーも、白い画面のちらつきも、ガタつきもありません。
これがbfcache(back/forward cache)の働きですが、ほとんどのチームにとっては目に見えない存在です。ダッシュボードがすべて緑で、Web Vitalsも健全、LCPが過去最高の数値だったとしても、bfcacheが待たずに行き来できる即時性を実現できていなければ、ユーザーが体感していてもチームはまったく気づくことができません。
今回、この死角に取り組みました。アプリケーションメトリクスのリリースにより、思いつく限りのブラウザのシグナルをグラフ化できる数値に変換できるようになったので、重要でるにもかかわらず、他のテレメトリデータ(スパンなど)では表に出てこなかったシグナルを探し始めるようになりました。その筆頭がbfcacheで、成果として生まれたのが新しいbfcacheMetricsIntegrationです。ブラウザが1日に何千回も、ほぼ何の知らせもなく下している判断を、計測・追跡・修正できるものに変えます。
bfcacheが重要な体験に与える影響
ページから移動すると、ブラウザは通常そのページを破棄します。スクリプトは停止し、メモリは解放され、DOMは消えます。あとで戻ってくると、ページはゼロから再構築され、リスナーが発火し、fetch呼び出しが一斉に走り、スピナーが回ります。
bfcacheはこれをすべて省略します。ブラウザはページをその場で凍結し、DOM、JavaScriptヒープ、スクロール位置など、すべてを含む完全なインメモリスナップショットとして保持します。
「戻る」や「進む」のナビゲーション時には、そのスナップショットを解凍してそのまま返します。読み込むものが何もないので、遷移は実質的に一瞬です。ページは実際には一度も消えていなかったのです。
これはニッチな最適化ではありません。戻る・進むのナビゲーションはWeb上で最も頻繁に使われる経路の一つで、体感速度がビジネス価値に直結しうるフローの大部分を占めています。たとえば、ECサイトでの商品ページと一覧ページの行き来、検索結果の行ったり来たり、ドキュメント、メディアの閲覧、マーケットプレイスなどです。また、効果が最も大きいのは低速なネットワークやデバイスを使うユーザーで、bfcacheがなければ「戻る」を押すたびにリロードのコストをすべて負担することになります。こうした導線では、「戻るボタンがどれだけ速いか」は最優先で考えるべきパフォーマンスの問いであり、多くの場合、新規ページ読み込みよりも大きな問題です。
違いは並べてみると一番よくわかります。ミスをすると、ページ全体をゼロから再構築し、再フェッチ・再レンダリングが走り、ユーザーがいた位置も失われます。
https://player.vimeo.com/video/1229898198?transparent=0&dnt=1
大事なのは「発見」
Sentryも含め、あらゆるパフォーマンスツールはページ読み込みのライフサイクルを軸に作られています。通常のツールから見ると、bfcacheヒットは「何も起きていない」のと区別がつかないため、戻る・進むのナビゲーションは見過ごされることがあります。
ここにはパラドックスがあります。bfcacheがうまく機能するほど、既存のツールが収集するデータは少なくなります。成功とは「無音」だからです。見えないものは追跡できませんし、最も健全なケースこそ何のトレース(痕跡)も残さないのです(あえての言葉遊びです)。
さらに厄介なのは、ページがbfcacheの対象になるかどうかをブラウザがヒューリスティクスで判断しており、その基準が時間とともに変わっていくため、ページが予期せず対象外になりうることです。
対象外になる理由はありふれたものです。unloadリスナー、Cache-Control: no-storeヘッダー、開いたままの接続、埋め込みiframe内のブロッカーなどが、これまでにページをキャッシュから締め出してきました。この記事を読むころには、その一部はもう当てはまらず、新しい理由に置き換わっているかもしれません。どれも、自分自身やサードパーティのスクリプトが気づかないうちに追加してしまう可能性があります。
つまり、対象かどうかは簡単なコード変更で後退することもあれば、コードをまったく変更しなくても後退することがあります。テストやコードレビューでこの後退を防ぐのは現実的ではなく、積極的に追跡して修正すべきものなのです。
アプリケーションメトリクスは、スパンやログにはない形で「発見」に向いています。ミスが急増したら、ルート、リリース、ブラウザと順に分解していけば、原因が見えてきます。「xはどうだろう?」と思ったら、クエリを1つ投げるだけ。再デプロイも新たなインストルメンテーションも必要ありません。
仕組み
必要な情報はすべてブラウザがすでに教えてくれています。pageshowイベントとnotRestoredReasons APIの両方が、ページがbfcacheの対象外だったかどうか、そしてその理由を正確に示してくれます。
bfcacheMetricsIntegrationは、これらのシグナルを3つのアプリケーションメトリクスとしてモデル化し(ブラウザのサポート状況によります)、それぞれにいくつかの属性を付与します。
browser.bfcache.navigation— 戻る・進むのナビゲーション1回につき1つ記録されるCounterで、以下の属性を持ちます。browser.bfcache.outcome—hitまたはmiss。browser.bfcache.not_restored_reason_count— ブラウザが報告した理由の数。
browser.bfcache.not_restored(Chromiumのみ) — ミス時に、復元されなかった理由1つにつき1つ記録されるCounterで、以下の属性を持ちます。browser.bfcache.reason— ブラウザが返す生の理由文字列。たとえばunload-listener、websocket、idbversionchangeevent、response-cache-control-no-storeなど。browser.bfcache.frame— ブロッカーがあった場所。メインドキュメントならtop、サブフレームならchild。
browser.bfcache.reload.duration— 戻る・進むのナビゲーションがミスした際に、代わりに発生したリロードにどれだけコストがかかったかを示すDistribution(ミリ秒単位)です。これが影響度を示すメトリクスです。復元が成功していたらどれだけ速かったかを知っているとは主張せず、ミスがユーザーに実際にどれだけのコストを与えたかを計測します。そのため、ブロッカーの単純な数ではなく、実際の痛みの大きさで優先順位をつけられます。
この3つに決めたのは、組み合わせることで戻る・進むのナビゲーションの全体像に答えられるからです。復元されたか?されなかったならなぜか?ミスによるコストはどれくらいか?
使い方
このインテグレーションは1行で有効化できます。

このインテグレーションはアプリケーションメトリクスを送信するので、一部の問いにしか答えられず常に調整が必要な出来合いのダッシュボードを渡されるのではなく、自分でダッシュボードを作ることができます。
エージェントによるダッシュボード作成を使えば、これらのメトリクスで何を見たいかをそのまま伝えられます。以下はその例です。
- 「bfcacheメトリクスを使って、全体のbfcacheヒット率と、過去1か月で上昇傾向か下降傾向かを確認したい」
- 「bfcacheメトリクスを使って、どのルートがbfcacheミスを最も多く引き起こしているかを確認し、優先的に修正したい」
- 「bfcacheメトリクスを使って、全体または特定のルートにおけるbfcacheミスの主な理由を確認したい」
ウィザードとチャットしながら、納得いくまでダッシュボードをさらに調整できます。
https://player.vimeo.com/video/1229897525?transparent=0&dnt=1
セットアップの詳細や、メトリクスと属性の完全なリストについては、bfcacheMetricsIntegrationのドキュメントをご覧ください。
戻るボタンの追跡を始めよう
このインテグレーションはオプトイン方式で、JavaScript SDKs v11でリリースされました。ヒットとミスの結果はモダンブラウザ全般で機能するため、今日からbfcacheの健全性を計測できます。復元されなかった理由の詳細は現在Chromium限定の機能ですが、notRestoredReasons APIを実装するエンジンが増えるにつれて、対応範囲は自然と広がっていきます。
また、Core Web Vitalsなど、これまでこうしたナビゲーションをカウントしていなかった機能にもbfcacheへの対応を広げています。復元されたページではpageloadが発生しないため、これらのVitalsには記録されていませんでした。bfcacheを組み込むことでこのギャップが埋まります。こうしたカバレッジは、ユーザーに気づいてもらうのを待つのではなく、あらかじめ組み込んでおきたいと考えています。
Original Page: Measuring the back/forward cache with Application Metrics
IchizokuはSentryと提携し、日本でSentry製品の導入支援、テクニカルサポート、ベストプラクティスの共有を行なっています。Ichizokuが提供するSentryの日本語サイトについてはこちらをご覧ください。またご導入についての相談は「お問い合わせ」からお気軽にお問い合わせください。

