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