はじめに
NoState プリフェッチは、<link rel="prerender">
などの機能に使用される非推奨のプリレンダリング プロセスに代わる、Chrome の新しいメカニズムです。プリレンダリングと同様に、リソースを事前に取得しますが、プリレンダリングとは異なり、JavaScript を実行したり、ページの一部を事前にレンダリングしたりしません。NoState プリフェッチの目的は、ページの読み込み時間を短縮しながら、プリレンダリングよりも少ないメモリを使用することです。
NoState Prefetch は API ではなく、Chrome がさまざまな API と機能を実装するために使用するメカニズムです。Resource Hints API と Chrome アドレスバーによるページのプリフェッチは、どちらも NoState Prefetch を使用して実装されています。Chrome 63 以降を使用している場合、ブラウザはすでに <link rel="prerender">
などの機能に NoState プリフェッチを使用しています。
この記事では、NoStatePrefetch の仕組み、導入の理由、Chrome のヒストグラムを使用して使用状況に関する統計情報を表示する手順について説明します。
目的
NoState プリフェッチを導入した主な理由は次の 2 つです。
メモリ使用量を削減する
NoState プリフェッチは約 45 MiB のメモリしか使用しません。プリロード スキャナの維持が NoState プリフェッチのメモリ費用の主な要因であり、この費用はユースケースが異なっても比較的一定です。フェッチのサイズや量を増やしても、NoState プリフェッチで消費されるメモリ量に大きな影響はありません。
一方、プリレンダリングでは通常 100 MiB のメモリが消費され、メモリ使用量は 150 MiB に制限されます。メモリ消費量が多いため、低価格帯(RAM 512 MB 以下)のデバイスには適していません。そのため、Chrome は低価格デバイスでプリレンダリングを行わず、代わりにプリコネクトを行います。
新しいウェブ プラットフォーム機能のサポートを容易にする
プリレンダリングでは、ユーザー向けのアクション(音楽や動画の再生など)やステートフル アクション(セッションやローカル ストレージの変更など)は発生しません。ただし、ページのレンダリング中にこれらのアクションが発生しないようにすることは、困難で複雑な場合があります。NoState プリフェッチは、リソースのみを事前に取得します。コードの実行やページのレンダリングは行いません。これにより、ユーザー向けのアクションとステートフル アクションの発生を簡単に防止できます。
実装
次の手順では、NoState プリフェッチの仕組みについて説明します。
NoStatePrefetch がトリガーされます。
プリレンダリング リソース ヒント(
<link rel="prerender">
)と一部の Chrome 機能は、次の 2 つの条件が満たされている場合に NoState プリフェッチをトリガーします。a)ユーザーがローエンド デバイスを使用していない、b)ユーザーがモバイル ネットワークを使用していない。NoState プリフェッチ用に新しい専用レンダラが作成されます。
Chrome では、「レンダラ」は、HTML ドキュメントの取得、解析、レンダリング ツリーの構築、結果の画面へのペイントを行うプロセスです。Chrome の各タブと各 NoState プリフェッチ プロセスには、分離を実現するための独自のレンダラがあります。これにより、問題が発生した場合の影響(タブのクラッシュなど)を最小限に抑え、悪意のあるコードが他のタブやシステムの他の部分にアクセスするのを防ぐことができます。
NoState プリフェッチで読み込まれているリソースがフェッチされます。HTMLPreloadScanner は、このリソースをスキャンして、取得する必要があるサブリソースを検出します。メインリソースまたはそのサブリソースに登録済みのサービス ワーカーがある場合、これらのリクエストは適切なサービス ワーカーを経由します。
NoState プリフェッチは GET HTTP メソッドのみをサポートします。他の HTTP メソッドの使用を必要とするサブリソースは取得しません。また、ユーザー操作が必要なリソース(認証ポップアップ、SSL クライアント証明書、手動オーバーライドなど)は取得されません。
フェッチされるサブリソースは、「アイドル」のネット優先度でフェッチされます。
「アイドル状態」のネット優先度は、Chrome で可能な限り低いネット優先度です。
NoState プリフェッチによって取得されたすべてのリソースは、キャッシュ ヘッダーに従ってキャッシュに保存されます。
NoState プリフェッチは、
no-store
Cache-Control ヘッダーを持つリソースを除くすべてのリソースをキャッシュに保存します。Vary
レスポンス ヘッダー、no-cache
Cache-Control ヘッダーがある場合、またはリソースが 5 分以上経過している場合は、リソースは使用前に再検証されます。すべてのサブリソースが読み込まれると、レンダラが強制終了します。
サブリソースがタイムアウトすると、レンダラは 30 秒後に強制終了されます。
ブラウザは、Cookie ストアとローカル DNS キャッシュの更新以外に、状態を変更しません。これは「NoState プリフェッチ」の「NoState」であるため、この点に注意してください。
「通常」のページ読み込みプロセスのこの時点で、ブラウザはブラウザの状態を変更する処理を行う可能性があります。たとえば、JavaScript の実行、
sessionStorage
またはlocalStorage
の変更、音楽や動画の再生、History API の使用、ユーザーへのプロンプトの表示などです。NoState プリフェッチで発生する状態の変更は、レスポンスの受信時に DNS キャッシュの更新と、レスポンスにSet-Cookie
ヘッダーが含まれている場合の Cookie ストアの更新のみです。リソースが必要になると、ブラウザ ウィンドウに読み込まれます。
ただし、事前レンダリングされたページとは異なり、ページはすぐに表示されません。ブラウザでレンダリングする必要があります。ブラウザは、NoState プリフェッチに使用したレンダラを再利用せず、代わりに新しいレンダラを使用します。ページを事前にレンダリングしないようにすると、NoStatePrefetch のメモリ消費量は減りますが、ページの読み込み時間に与える影響も軽減されます。
ページに Service Worker がある場合、このページの読み込みは Service Worker を再度経由します。
ページが必要な時点で NoState プリフェッチがサブリソースの取得を完了していない場合、ブラウザは NoState プリフェッチが停止したところからページ読み込みプロセスを続行します。ブラウザは引き続きリソースを取得する必要がありますが、NoState プリフェッチが開始されていなかった場合に必要な数ほどではありません。
ウェブ解析への影響
NoState プリフェッチを使用して読み込まれたページは、ツールがクライアントサイドでデータを収集するか、サーバーサイドで収集するかに応じて、ウェブ アナリティクス ツールによって登録されるタイミングが若干異なります。
クライアントサイド アナリティクス スクリプトは、ページがユーザーに表示されたときにページビューを登録します。これらのスクリプトは JavaScript の実行に依存していますが、NoState プリフェッチは JavaScript を実行しません。
サーバーサイド分析ツールは、リクエストが処理されたときに指標を登録します。NoState プリフェッチを介して読み込まれたリソースの場合、リクエストが処理されてから、レスポンスがクライアントによって実際に使用されるまでの時間に大きな差が生じる可能性があります(使用される場合)。Chrome 69 以降、NoState プリフェッチでは、通常のブラウジングと区別できるように、すべてのリクエストにヘッダー Purpose: Prefetch
が追加されます。
今すぐチェック
NoStatePrefetch は 2017 年 12 月の Chrome 63 でリリースされました。現在、次の目的で使用されています。
prerender
リソースヒントを実装する- Google 検索の検索結果の 1 番目の結果を取得する
- Chrome のアドレスバーが次にアクセスされる可能性が高いと予測したページを取得する
Chrome Internals を使用すると、NoStatePrefetch の使用状況を確認できます。
NoState プリフェッチで読み込まれたサイトのリストを表示するには、chrome://net-internals/#prerender にアクセスします。
NoState Prefetch の使用状況に関する統計情報を表示するには、chrome://histograms に移動して「NoStatePrefetch」を検索します。NoState Prefetch のユースケースごとに 3 つの NoState Prefetch ヒストグラムがあります。
- 「NoStatePrefetch」(プリレンダリング リソース ヒントによる使用状況の統計情報)
- 「gws_NoStatePrefetch」(Google 検索の検索結果ページでの使用状況に関する統計情報)
- 「omnibox_NoStatePrefetch」(Chrome のアドレスバーでの使用状況の統計情報)