ブログに戻る

Speculation RulesとPrerendering:先読みされたページについてアナリティクスが誤解していること

ChromeのSpeculation Rules APIは、ユーザーがクリックする前にページをレンダリングできます。それがいかにして単純なアナリティクスを歪めるのか、そしてクッキーレスでエッジベースの計測がどのように正直であり続けるのかを解説します。

クリックの前に読み込まれたページ

Speculation Rules APIは、現在Chromiumブラウザで広く提供されており、サイトがどのURLをナビゲーションに先立ってブラウザに prefetch または完全に prerender させるべきかを宣言できるようにします。ユーザーがホバーしたり意図を示したりすると、遷移先はすでに隠しタブでレンダリングされており、瞬時に切り替えられます。その恩恵は、アクティベーション時にほぼゼロのLargest Contentful Paintを得られることです。しかし計測にとっての問題は、prerenderされたページが 誰もそのページを訪れると決める前に あなたのスクリプトを実行してしまうことです。

もしアナリティクスが読み込み時にページビューを発火するなら、prerenderは実際には起こらなかった訪問でカウントを水増ししてしまいます。さらに悪いことに、パフォーマンスデータも歪めます。バックグラウンドでprerenderされたページは、実際のユーザーが体験したものとは何の関係もないタイミングを記録するのです。

prerender中に実際に起こること

prerenderされたドキュメントは通常どおり実行されますが、特別なライフサイクル状態にあります。document.prerenderingtrue であり、ページはまだ可視タブへアクティベートされていません。prerenderingchange イベントは、ユーザーが実際にそこへナビゲートした場合に「のみ」発火します。多くのprerenderは一度もアクティベートされないままであり、ブラウザはそれらを破棄することがあります。

これが重要なのは2つの理由からです:

  1. カウント。 DOMContentLoaded での単純な sendBeacon は、決して見られないかもしれないドキュメントについてページビューを報告してしまいます。
  2. パフォーマンスの帰属。 Core Web Vitalsは ユーザーが体感する 読み込みを基準に定義されています。web-vitalsライブラリや、その基盤となるPaint TimingおよびEvent Timingの仕様は、元のナビゲーション開始時点ではなくアクティベーション時点から計測することでprerenderを考慮します。その認識なしに収集された指標は、端的に言って間違っています。

正しいパターン

ウェブプラットフォームはクリーンなシグナルを提供します。ページが本当に人に見えるようになるまで、あらゆる計測を遅延させましょう:

if (document.prerendering) {
  document.addEventListener('prerenderingchange', recordPageview, { once: true });
} else {
  recordPageview();
}

タイミングについては、PerformanceNavigationTiming.activationStart がナビゲーション開始とアクティベーションの間のオフセットを与えてくれます。paintやインタラクションのタイムスタンプはすべてその値を基準に計測し、負の値はゼロにクランプすべきです。これはまさにGoogleのweb-vitalsライブラリが内部的に行っていることなので、LCPやINPを自分で計算するなら、そのロジックを踏襲してください。

同じ規律はprefetch、つまりprerenderの軽量な従兄弟にも当てはまります。prefetchはレスポンスを取得するだけでスクリプトを実行しないため、アナリティクスを直接汚染することはめったにありません。しかし帯域を消費し、サーバーサイドのリクエストログを歪めることはあります。生のログカウントと本物の訪問がこれまで以上に乖離していることを思い出させてくれます。

クッキーやクライアント状態がない方が容易な理由

Speculationによって駆動されるprerenderは、ステートフルなトラッカーにとって頭痛の種です。識別子を設定したり、セッションをハイドレートしたり、ストレージに書き込んだりするprerenderされたドキュメントは、破棄されるかもしれない訪問のために投機的にそれを行います。それをクリーンアップし、最終的な本物のアクティベーションと重複排除し、ページをまたいだアイデンティティを調整することは、真のエラーとプライバシーリスクの源になります。

Monoidはこの種の問題を丸ごと回避します。私たちはデバイスに何も保存しません——クッキーも localStorage もフィンガープリントもありません。作成して後で取り消す必要のある投機的なセッションは存在しません。計測は単一のステートレスなシグナルであり、ページが本物になったときにのみ発信します。収集はCloudflareのエッジで実行されるため、集計はブラウザの楽観的な推測ではなく、すでに本物のアクティベートされたナビゲーションを反映したデータに対して行われます。

これはデータ最小化があなたに有利に働いている例です。クリーンアップが必要なものを何も収集しなければ、投機的なレンダリングは孤立したアイデンティティレコードや重複プロファイルを生み出しません。それは単に、カウントする前に prerenderingchange を待つということを意味するだけです。

prerenderに安全なアナリティクスのためのチェックリスト

  • ページビューの発信を document.prerenderingprerenderingchange イベントでゲートする。
  • LCP、FCP、INPを activationStart を基準に計算するか、すでにそうしているライブラリを使う。
  • サーバーのリクエストログを本物の訪問の上位集合として扱い、その代理としては扱わない。
  • Content-Security-Policyが、アクティベートされたドキュメントから計測エンドポイントに到達することを許可しているか確認する。Chrome DevToolsのprerenderペインでテストする。
  • デバイスストレージへの投機的な書き込みを避ける——prerenderに正しくある最もクリーンな方法は、クライアント状態をまったく保持しないことです。

より広い視点

新しいパフォーマンスの基本要素——bfcache、ソフトナビゲーション、そして今回のspeculation rules——はそれぞれ、ページの読み込みが人間の訪問に等しいという古い前提を静かに崩していきます。クッキーとステートフルなセッションに依存するアナリティクスは、ますます多くの調整ロジックを付け足さなければなりません。本物の可視性の瞬間にステートレスなイベントを計測するアナリティクスは、プラットフォームのライフサイクルイベントを尊重するだけで済みます。高速なページと正直な数字は対立しません。ただ、適切な瞬間にカウントすればよいのです。

Sources

Comments

Loading comments…