署名付きエクスチェンジを測定して最適化し、最大限に改善する方法
署名付きエクスチェンジ(SXG)は、ページ速度(主に Largest Contentful Paint(LCP))を改善する手段です。参照元サイト(現在は Google 検索)がページにリンクを設定する場合、ユーザーがリンクをクリックする前に、そのページをブラウザ キャッシュにプリフェッチできます。
プリフェッチ時に、ページのレンダリングに必要なクリティカル パスでネットワークを必要としないウェブページを作成できます。4G 接続では、このページ読み込みが 2.8 秒から 0.9 秒になりました(残りの 0.9 秒は主に CPU 使用率によるものです)。
現在、SXG を公開しているほとんどのユーザーは、Cloudflare の使いやすい自動署名交換(ASX)機能を使用しています(オープンソース オプションもあります)。
多くの場合、チェックボックスをオンにすれば、上記のような大幅な改善が可能です。場合によっては、これらの SXG がパイプラインの各段階で意図したとおりに動作していることを確認し、プリフェッチを最大限に活用するためにページを最適化するために、さらにいくつかの手順があります。
Cloudflare のリリースから数か月間、私はさまざまな フォーラムで寄せられた質問を読んで回答し、SXG デプロイを最大限に活用する方法についてサイトにアドバイスする方法を学びました。この投稿では、私がこれまでに提供してきたアドバイスをまとめています。手順は次のとおりです。
- WebPageTest を使用して SXG のパフォーマンスを分析します。
- Analyze ステップで SXG パイプラインが機能しないことが示された場合は、SXG パイプラインをデバッグします。
- 最適な
max-age
の設定やレンダリングをブロックするサブリソースのプリロードなど、SXG プリフェッチ用にページを最適化します。 - 適切なテストグループとコントロール グループを選択し、Google アナリティクスを使用して SXG の改善を測定します。
はじめに
SXG は、URL、一連の HTTP レスポンス ヘッダー、レスポンス本文を含むファイルです。これらはすべて、Web PKI 証明書によって暗号署名されています。ブラウザは SXG を読み込む際に、次のすべてを検証します。
- SXG の有効期限が切れていないこと。
- 署名は、URL、ヘッダー、本文、証明書と照合されます。
- 証明書が有効で、URL と一致している。
検証が失敗した場合、ブラウザは SXG を破棄し、代わりに署名付き URL を取得します。検証が成功すると、ブラウザは署名付きレスポンスを読み込み、署名付き URL から直接送信されたものとして扱います。これにより、署名後に期限切れになったり変更されたりしていない限り、任意のサーバーに SXG を再ホストできます。
Google 検索の場合、SXG により検索結果のページのプリフェッチが可能になります。SXG をサポートするページの場合、Google 検索は webpkgcache.com でホストされているページのキャッシュ コピーをプリフェッチできます。ブラウザは元の署名付き URL を尊重するため、これらの webpkgcache.com の URL はページの表示や動作には影響しません。プリフェッチを使用すると、ページの読み込み時間を大幅に短縮できます。
分析
SXG のメリットを確認するには、まずラボツールを使用して、再現可能な条件で SXG のパフォーマンスを分析します。WebPageTest を使用して、SXG プリフェッチありとなしでのウォーターフォール(および LCP)を比較できます。
次のように、SXG のないテストを生成します。
- WebPageTest にアクセスしてログインします。ログインすると、テスト履歴が保存され、後で簡単に比較できます。
- テストする URL を入力します。
- [詳細設定] に移動します。(SXG テストには高度な構成が必要になるため、ここで使用するとテスト オプションが同じになります)。
- [テスト設定] タブで、[接続] を 4G に設定し、[実行するテストの数] を 7 に増やすとよいでしょう。
- [テストを開始] をクリックします。
上記と同じ手順で SXG でテストを生成しますが、[Start Test] をクリックする前に [Script] タブに移動し、次の WebPageTest スクリプトを貼り付けて、2 つの navigate
URL を指示どおりに変更します。
// Disable log collection for the first step. We only want the waterfall for the target navigation.
logData 0
// Visit a search result page that includes your page.
navigate https://google.com/search?q=site%3Asigned-exchange-testing.dev+image
// Wait for the prefetch to succeed.
sleep 10
// Re-enable log collection.
logData 1
// Navigate to the prefetched SXG on the Google SXG Cache.
navigate https://signed--exchange--testing-dev.webpkgcache.com/doc/-/s/signed-exchange-testing.dev/sxgs/valid-image-subresource.html
最初の navigate
URL について、まだ Google 検索の検索結果にページが表示されない場合は、こちらのプリフェッチ ページを使用して、偽装検索結果ページを生成できます。
2 番目の navigate
URL を確認するには、SXG Validator Chrome 拡張機能を使用してページにアクセスし、拡張機能アイコンをクリックしてキャッシュ URL を表示します。
テストが完了したら、[テスト履歴] に移動し、2 つのテストを選択して [比較] をクリックします。
比較 URL に &medianMetric=LCP
を追加して、WebPageTest が比較の両側について LCP の中央値の実行を選択するようにします。(デフォルトは Speed Index の中央値です)。
ウォーターフォールを比較するには、[ウォーターフォールの不透明度] セクションを開き、スライダーをドラッグします。動画を表示するには、[フィルムストリップの設定を調整] をクリックし、ダイアログ内で下にスクロールして [動画を表示] をクリックします。
SXG プリフェッチが成功すると、「with SXG」ウォーターフォールに HTML の行が含まれず、サブリソースの取得がより早く開始されます。たとえば、次の「前」と「後」を比較します。
デバッグ
WebPageTest で SXG がプリフェッチされていると表示される場合、パイプラインのすべてのステップが成功しています。[最適化] セクションに進んで、LCP をさらに改善する方法を確認してください。エラーがパイプラインのどの部分で発生し、なぜ発生したのかを特定する必要があります。方法については、以下をご覧ください。
公開
ページが SXG として生成されていることを確認します。そのためには、クローラーのふりをする必要があるのです。最も簡単な方法は、Chrome 拡張機能の SXG Validator を使用する方法です。
拡張機能は、SXG バージョンを優先することを示す Accept
リクエスト ヘッダーを使用して現在の URL を取得します。[送信元] の横にチェックマーク(✅)が表示されている場合は、SXG が返されたことを意味します。インデックス処理のセクションに進むことができます。
バツ印(❌)が表示される場合は、SXG が返されなかったことを意味します。
Cloudflare ASX が有効になっている場合、クロスマーク(❌)が表示される最も一般的な理由は、キャッシュ制御レスポンス ヘッダーが原因でキャッシュに保存できないためです。ASX は、次の名前のヘッダーを参照します。
Cache-Control
CDN-Cache-Control
Surrogate-Control
Cloudflare-CDN-Cache-Control
これらのヘッダーのいずれかに次のヘッダー値が含まれている場合、SXG は生成されません。
private
no-store
no-cache
max-age
は 120 未満(120 以上のs-maxage
でオーバーライドしない限り)
このような場合、ASX は SXG を作成しません。SXG は、複数回のアクセスや複数のユーザーのアクセスに対してキャッシュされ、再利用される可能性があるためです。
クロスマーク(❌)が表示されるもう 1 つの理由として、Set-Cookie
を除くこれらのステートフル レスポンス ヘッダーのいずれかが存在することも考えられます。ASX は、SXG 仕様に準拠するために Set-Cookie
ヘッダーを削除します。
Vary: Cookie
レスポンス ヘッダーが存在することも原因として考えられます。Googlebot はユーザーの認証情報なしで SXG を取得し、複数のユーザーに配信することがあります。Cookie に基づいて異なるユーザーに異なる HTML を配信すると、ログアウトしたビューなど、正しくないエクスペリエンスが表示される可能性があります。
Chrome 拡張機能の代わりに、curl
などのツールを使用することもできます。
curl -siH "Accept: application/signed-exchange;v=b3" $URL | less
または dump-signedexchange
:
dump-signedexchange -verify -uri $URL
SXG が存在していて有効な場合は、SXG が人が読める形式で出力されます。そうしないと、エラー メッセージが表示されます。
インデックス登録
SXG が Google Search によって正常にインデックスに登録されていることを確認します。Chrome DevTools を開き、ページの Google 検索を実行します。SXG としてインデックスに登録されている場合、Google のページへのリンクには、webpkgcache.com のコピーを指す data-sxg-url
が含まれます。
ユーザーが検索結果をクリックする可能性が高いと Google 検索が判断した場合は、その検索結果もプリフェッチされます。
<link>
要素は、SXG をプリフェッチ キャッシュにダウンロードするようブラウザに指示します。ユーザーが <a>
要素をクリックすると、ブラウザはキャッシュに保存された SXG を使用してページをレンダリングします。
DevTools の [ネットワーク] タブに移動し、webpkgcache
を含む URL を検索すると、プリフェッチの証拠を確認することもできます。
<a>
が webpkgcache.com を指している場合、Signed Exchange の Google 検索でのインデックス登録が機能していることを意味します。スキップして取り込みのセクションまで進むことができます。
そうでない場合は、SXG を有効にした後、Google がまだページを再クロールしていない可能性があります。Google Search Console の URL 検査ツールをお試しください。
digest: mi-sha256-03=...
ヘッダーが存在する場合は、Google が SXG バージョンを正常にクロールしたことを示します。
digest
ヘッダーが存在しない場合、SXG が Googlebot に配信されていないか、SXG を有効にした後でインデックスが更新されていないことを示している可能性があります。
SXG が正常にクロールされてもリンクされていない場合は、SXG キャッシュ要件を満たしていない可能性があります。これらについては、次のセクションで説明します。
取り込み
Google 検索が SXG をインデックス登録すると、そのコピーが Google SXG キャッシュに送信され、キャッシュ要件に基づいて検証されます。Chrome 拡張機能に結果が表示されます。
チェックマーク(✅)が表示されている場合は、[最適化] に進んでください。
要件を満たしていない場合は、× マーク(❌)と、その理由を示す警告メッセージが表示されます。
この場合、ページは SXG を有効にする前と同じように動作します。Google は、SXG プリフェッチなしで元のホストのページにリンクします。
キャッシュに保存されたコピーの有効期限が切れてバックグラウンドで再取得されている場合は、砂時計(⌛)が表示されます。
SXG に関する Google デベロッパー ドキュメントにも、キャッシュを手動でクエリする手順が記載されています。
最適化
Chrome 拡張機能の SXG Validator にすべてのチェックマーク(✅)が表示されている場合は、ユーザーに配信できる SXG が作成されています。SXG で LCP を最大限改善できるようにウェブページを最適化する方法については、以下をご覧ください。
最大年齢
SXG が期限切れになると、Google SXG Cache はバックグラウンドで新しいコピーを取得します。フェッチを待っている間、ユーザーは元のホストのページにリダイレクトされますが、このページはプリフェッチされません。Cache-Control: max-age
を長く設定すると、このバックグラウンド フェッチの頻度が低下し、プリフェッチによって LCP を短縮できる頻度が高くなります。
これはパフォーマンスと更新頻度のトレードオフです。キャッシュを使用すると、サイト所有者は各ページの特定のニーズに合わせて、2 分~7 日の範囲で SXG の有効期限を指定できます。経験則では、次のようなことがわかります。
max-age=86400
(1 日)以上はパフォーマンスに適していますmax-age=120
(2 分)は次を行いません
今後、データをさらに調査し、この 2 つの値の間にある値について詳しく把握したいと考えています。
user-agent
プリフェッチされた SXG を使用した際に、LCP が増加したことがあります。WebPageTest を実行し、SXG プリフェッチありとなしでの中央値を比較しました。下記の [After] をクリックします。
プリフェッチが機能していることを確認しました。HTML がクリティカル パスから削除されるため、すべてのサブリソースをより早く読み込むことができます。一方、LCP(緑色の点線)は2 秒から 2.1 秒に増加しました。
この問題を診断するため、フィルム ストリップを確認しました。SXG ではページの表示が異なることがわかりました。プレーン HTML では、Chrome は LCP の「最大要素」をヘッドラインと判断しました。しかし SXG バージョンでは遅延読み込みバナーが追加され、見出しがスクロールしなければ見えない位置に押し出され、新しい大きな要素が遅延読み込みの Cookie 同意ダイアログになりました。すべてのレンダリングが以前より速くなりましたが、レイアウトが変更されたため、指標の表示が遅くなっています。
詳しく調べたところ、レイアウトが異なる理由は、ページが User-Agent
によって異なり、ロジックにエラーがあったことがわかりました。SXG クロール ヘッダーがモバイルを示しているにもかかわらず、パソコン向けのページが配信されていました。この修正後、ブラウザはページの見出しを最大の要素として再び正しく識別しました。
[After] をクリックすると、プリフェッチされた LCP が1.3 秒に短縮されました。
SXG はすべてのフォーム ファクタで有効になっています。そのためには、次のいずれかを確認してください。
- ページが
User-Agent
によってVary
されていない(レスポンシブ デザインやモバイルとパソコンの URL が別々になっているなど)。 - ページで動的な配信を使用している場合は、
<meta name=supported-media content=...>
を使用して「モバイルのみ」または「パソコンのみ」のアノテーションが追加されます。
サブリソース
SXG を使用すると、HTML とともにサブリソース(画像を含む)をプリフェッチできます。Cloudflare ASX は、HTML をスキャンして同じオリジン(ファーストパーティ)の <link rel=preload>
要素を検出し、SXG 互換のリンク ヘッダーに変換します。詳細については、こちらとこちらのソースコードをご覧ください。
正しく動作している場合は、Google 検索からさらにプリフェッチが表示されます。
LCP を最適化するには、ウォーターフォールを詳しく調べ、最大要素のレンダリングに必要なクリティカル パス上にあるリソースを特定します。プリフェッチできない場合は、クリティカル パスから除外できるかどうかを検討します。読み込みが完了するまでページを非表示にするスクリプトに注意してください。
Google SXG キャッシュでは、最大 20 個のサブリソースのプリロードが許可され、ASX は、この上限が超過しないように保証します。ただし、サブリソースのプリロードを追加しすぎると、ブラウザは、クロスサイト トラッキングを防止するために、プリロードされたサブリソースをすべて取得が完了した場合のみ使用します。サブリソースが多いほど、ユーザーがページに移動する前にすべてのサブリソースのプリフェッチが完了する可能性は低くなります。
現時点では、SXG Validator はサブリソースをチェックしません。デバッグするには、その間に curl
または dump-signedexchange
を使用します。
測定
WebPageTest で LCP の改善を最適化したら、SXG プリフェッチがサイトの全体的なパフォーマンスに与える影響を測定することをおすすめします。
サーバーサイドの指標
最初の 1 バイトまでの時間(TTFB)などのサーバーサイド指標を測定する際は、サイトが SXG を提供するクロールツールは、その形式をサポートしているものだけであることを覚えておくことが重要です。TTFB の測定は、ボットではなく実際のユーザーからのリクエストに限定します。SXG の生成によりクローラー リクエストの TTFB が長くなる場合がありますが、ユーザーのエクスペリエンスには影響しません。
クライアントサイドの指標
SXG は、クライアントサイドの指標(特に LCP)の速度向上に最も効果的です。影響を測定する場合は、Cloudflare ASX を有効にして、Googlebot によって再クロールされるのを待ってから、Core Web Vitals(CWV)の集計までさらに 28 日間待ってから、新しい CWV 数を確認するだけです。ただし、この期間中の他の変更と混ざってみると、その変更を特定するのが難しい場合があります。
代わりに、影響を受ける可能性のあるページ読み込みに「ズームイン」し、「SXG はページビューの X% に影響し、75 パーセンタイルにおいて LCP を Y ミリ秒改善しました」というように表現することをおすすめします。
現在、SXG プリフェッチは特定の条件下でのみ行われます。
- Chromium ブラウザ(iOS を除く Chrome または Edge)、バージョン M98 以降
Referer: google.com
またはその他の Google 検索ドメイン。(Google アナリティクスでは、参照元タグはセッション内のすべてのページビューに適用されますが、SXG プリフェッチは Google 検索から直接リンクされた最初のページビューにのみ適用されます)。
「X% のページビュー」と「LCP を Y ミリ秒改善」を測定する方法については、最新の調査セクションをご覧ください。
現代の研究
リアルユーザー モニタリング(RUM)データを確認する際は、ページ読み込みを SXG と SXG 以外に分割する必要があります。選択バイアスを回避するには、SXG 以外の側が SXG の資格要件を満たすように、対象とするページ読み込みのセットを制限することが重要です。そうでない場合、次のすべてが SXG 以外のページ読み込みのセットにのみ存在し、LCP が本質的に異なる可能性があります。
- iOS デバイス: これらのデバイスを使用しているユーザーのハードウェアやネットワーク速度が異なるためです。
- 古い Chromium ブラウザ: 同じ理由です。
- パソコン: 上記と同じ理由、またはページ レイアウトによって別の「最大要素」が選択されるため。
- 同一サイト内ナビゲーション(サイト内のリンクをたどる訪問者): 前回のページ読み込みでキャッシュに保存されたサブリソースを再利用できるからです。
Google アナリティクス(UA)で、スコープが「ヒット」の2 つのカスタム ディメンションを作成します。1 つは「isSXG」、もう 1 つは「referrer」という名前にします。(組み込みの「ソース」ディメンションにはセッション スコープが設定されているため、同一サイト ナビゲーションは除外されません)。
次のフィルタを AND 演算で結合して、「SXG 対照実験」という名前のカスタム セグメントを作成します。
- 「
referrer
」の先頭が「https://www.google.
」と一致 Browser
はChrome
と完全に一致するBrowser
バージョンが正規表現に一致^(9[8-9]|[0-9]{3})
isSXG
はfalse
と完全に一致する
このセグメントのコピーを「SXG」という名前で作成します。ただし、「isSXG
」は「true
」と完全に一致します。
サイト テンプレートで、Google アナリティクスのスニペットの上に次のスニペットを追加します。これは、SXG の生成時に ASX が false
を true
に変更する特別な構文です。
<script data-issxg-var>window.isSXG=false</script>
推奨方法に沿って Google アナリティクスのレポート スクリプトをカスタマイズし、LCP を記録します。gtag.js を使用している場合は、'config'
コマンドを変更してカスタム ディメンションを設定します('dimension1'
と 'dimension2'
は、Google アナリティクスで使用するよう指定されている名前に置き換えてください)。
gtag('config', 'YOUR_TRACKING_ID', {
'dimension1': String(isSXG),
'dimension2': document.referrer,
});
analytics.js を使用している場合は、こちらに記載されているように 'create'
コマンドを変更します。
データが収集されるまで数日待ってから、Google アナリティクスのイベント レポートに移動し、SXG セグメントのドリルダウンを追加します。これにより、「SXG が X% のページビューに影響している」の X が入力されます。
最後に、ウェブバイタル レポートに移動し、[セグメントを選択] を選択して、[SXG 対照群] と [SXG] を選択します。
[送信] をクリックすると、2 つのセグメントの LCP 分布が表示されます。これにより、「75 パーセンタイルにおいて LCP を Y ミリ秒改善」の Y が入力されます。
注意点
上記のフィルタをすべて適用すると、SXG の反実仮想ページ読み込みは次のような内容になります。
- キャッシュに一致するデータがない: 特定の URL の SXG の最新のコピーが Google SXG キャッシュにない場合、サイトの元の URL にリダイレクトされます。
- その他の検索結果タイプ: 現在、Google 検索でサポートされているのは、標準のウェブ検索結果とその他のいくつかのタイプの SXG のみです。一方、強調スニペットやトップニュース カルーセルなどでは、サイトの元の URL にリンクされます。
- 対象外の URL: サイト上の一部のページが SXG の対象外(キャッシュに保存できないなど)である場合、このセットに表示されることがあります。
SXG ページの読み込みと、上記の SXG 以外のページの読み込みの間に残るバイアスがある可能性がありますが、そのバイアスは最新の調査セクションの上部に記載されているバイアスよりも小さいはずです。たとえば、キャッシュに保存できないページがキャッシュに保存できるページよりも遅い場合や、速い場合があります。これが問題であると思われる場合は、特定の SXG 対象 URL に限定したデータを調べて、その結果が全体的な調査と一致するかどうかを確認することをおすすめします。
サイトに AMP ページがある場合、SXG を有効にしてもパフォーマンスの向上は見られません。これらのページはすでに Google 検索からプリフェッチされる可能性があるためです。関連する変更をさらに「拡大」するには、そのようなページを除外するフィルタを追加することを検討してください。
最後に、選択バイアスをすべて解消しても、生存バイアスによって LCP の改善が RUM 統計情報の低下のように見えるリスクがあります。こちらの記事では、そのリスクについて詳しく説明しています。また、放棄が発生しているかどうかを検出するために、なんらかの放棄指標を確認することをおすすめしています。
前後比較調査
最新の調査結果を裏付けるために、SXG を有効にする前と後で LCP を比較すると役立つ場合があります。上記の潜在的なバイアスを排除するため、SXG ページビューに限定しないでください。代わりに、SXG の対象となる結果(上記のセグメント定義で isSXG
制約がないもの)を確認します。
なお、Google 検索がサイト上のすべてのページを再クロールして SXG が有効になっていることを確認するまでに、数週間かかることがあります。この数週間の間に、他にもバイアスが発生する可能性があります。
- 新しいブラウザのリリースやユーザーのハードウェアの改善により、ページの読み込み時間が短縮される場合があります。
- 祝日などの重要なイベントによって、トラフィックが通常から偏ることがあります。
また、上記の調査を確認するために、全体的な 75 パーセンタイル LCP の前後を確認することも有用です。母集団の一部について学習しても、母集団全体を把握できるとは限りません。たとえば、SXG によってページ読み込みの 10% が 800 ミリ秒短縮されたとします。
- これらのページの読み込みがすでに上位 10% に含まれている場合、75 パーセンタイルにはまったく影響しません。
- 最も遅いページ読み込みの 10% でも、そもそも 75 パーセンタイルの LCP よりも 800 ミリ秒以上遅かった場合、75 パーセンタイルにはまったく影響しません。
これらは極端な例であり、現実を反映していない可能性はありますが、問題を説明できれば幸いです。実際には、SXG はほとんどのサイトで 75 パーセンタイルに影響する可能性があります。クロスサイト ナビゲーションは最も遅い傾向があり、プリフェッチによって大幅な改善が見込めます。
一部の URL をオプトアウトする
最後に、SXG のパフォーマンスを比較する 1 つの方法は、サイト上の一部の URL で SXG を無効にすることです。たとえば、CDN-Cache-Control: no-store
ヘッダーを設定して、Cloudflare ASX が SXG を生成しないようにできます。おすすめしません。
他の調査方法よりも選択バイアスのリスクが高くなります。たとえば、サイトのホームページと同様の人気を誇る URL のどちらがコントロール グループとテストグループに選択されるかによって、結果に大きな違いが生じる可能性があります。
ホールドバック スタディ
影響の測定に最適な方法は、ホールドバック テストを実施することです。残念ながら、現在のところこのようなテストは行えません。今後、このようなテストのサポートを追加する予定です。
ホールドバック テストには次のプロパティがあります。
- テストグループでは、SXG になるページビューの一部がランダムに「保留」され、代わりに SXG 以外のページビューとして配信されます。これにより、同等のユーザー、デバイス、シナリオ、ページを同じ条件で比較できます。
- 抑制された(反事実的)ページビューは、アナリティクスでそのようにラベル付けされます。これにより、データを「拡大」して、コントロールの SXG のページ読み込みとテストの SXG の反事実的データを比較できます。これにより、SXG プリフェッチの影響を受けない他のページ読み込みによるノイズが軽減されます。
これにより、前述の選択バイアスの原因を排除できますが、LCP の存続バイアスのリスクを排除することはできません。どちらのプロパティも、ブラウザまたは参照元のいずれかを有効にする必要があります。
まとめ
ぜひ多いね。ラボテストで SXG のパフォーマンスをテストする方法、ラボテストと緊密なフィードバック ループでパフォーマンスを最適化する方法、そして最終的に実環境でパフォーマンスを測定する方法について、より包括的な理解を深めてもらえれば幸いです。これらをすべて組み合わせることで、SXG を最大限に活用し、SXG がサイトとユーザーにメリットをもたらすようにすることができます。
SXG のパフォーマンスを高める方法について、他にご提案がございましたら、お気軽にお問い合わせください。改善の提案について developer.chrome.com でバグを報告してください。
署名付きエクスチェンジの詳細については、web.dev のドキュメントと Google 検索のドキュメントをご覧ください。