プリフェッチ、事前レンダリング、Service Worker の事前キャッシュ

これまでのいくつかのモジュールでは、JavaScript の読み込みを延期する画像と <iframe> 要素の遅延読み込みなどのコンセプトを確認しました。リソースの読み込みを延期すると、未使用の可能性があるリソースをあらかじめ読み込むのではなく、リソースが必要になった時点でダウンロードされるため、最初のページ読み込み時のネットワークと CPU の使用率が低減されます。これにより、最初のページの読み込み時間は短縮できますが、後続のインタラクションの発生時にリソースの読み込みに必要なリソースがまだ読み込まれていない場合、遅延が発生する可能性があります。

たとえば、ページにカスタムの日付選択ツールが含まれている場合は、ユーザーがその要素を操作するまで、日付選択ツールのリソースの表示を遅らせることができます。ただし、日付選択ツールのリソースをオンデマンドで読み込むと、リソースがダウンロードされて解析されて実行可能になるまで、ユーザーのネットワーク接続やデバイスの機能によってはわずかですが、遅延が生じることがあります。

このバランスは厄介です。使用されないリソースの読み込みで帯域幅を浪費したくはありませんが、インタラクションや後続のページの読み込みが遅れることも望ましくありません。幸いなことに、この 2 つの極端なバランスを取るために使用できるツールはいくつかあります。このモジュールでは、リソースのプリフェッチ、ページ全体の事前レンダリング、Service Worker を使用したリソースの事前キャッシュなど、そのために使用できるいくつかの手法について説明します。

近い将来必要となるリソースを低い優先度でプリフェッチする

<link rel="prefetch"> リソースヒントを使用すると、画像、スタイルシート、JavaScript リソースなどのリソースを前もって取得できます。prefetch ヒントは、リソースが近い将来必要になる可能性があることをブラウザに通知します。

prefetch ヒントを指定すると、ブラウザは現在のページに必要なリソースとの競合を避けるため、最も優先度の低いリソースでリクエストを開始できます。

リソースをプリフェッチすると、必要なときにディスク キャッシュからすぐに取得できるため、近い将来に必要なリソースがダウンロードされるのを待つ必要がなくなるため、ユーザー エクスペリエンスが向上します。

<head>
  <!-- ... -->
  <link rel="prefetch" as="script" href="/date-picker.js">
  <link rel="prefetch" as="style" href="/date-picker.css">
  <!-- ... -->
</head>

上記の HTML スニペットは、アイドル状態になると date-picker.jsdate-picker.css をプリフェッチできることをブラウザに通知します。ユーザーが JavaScript でページを操作すると、リソースを動的にプリフェッチすることもできます。

prefetch は Safari を除くすべての最新ブラウザでサポートされています。Safari ではフラグが設定されている場合のみ利用できます。どのブラウザでも機能するようにウェブサイトのリソースをあらかじめ読み込む必要があり、Service Worker を使用している場合は、このモジュールの後半にある Service Worker を使用したリソースの事前キャッシュをご覧ください。

ページをプリフェッチして以降の移動時間を短縮

HTML ドキュメントを指すときに as="document" 属性を指定することで、ページとそのすべてのサブリソースをプリフェッチすることもできます。

<link rel="prefetch" href="/page" as="document">

ブラウザがアイドル状態になると、/page に対して優先度の低いリクエストが開始されることがあります。

Chromium ベースのブラウザでは、Speculation Rules API を使用してドキュメントをプリフェッチできます。推測ルールは、ページの HTML に含まれる JSON オブジェクトとして定義されるか、JavaScript を使用して動的に追加されます。

<script type="speculationrules">
{
  "prefetch": [{
    "source": "list",
    "urls": ["/page-a", "/page-b"]
  }]
}
</script>

JSON オブジェクトは、1 つ以上のアクション(現在は prefetchprerender のみをサポートしています)と、そのアクションに関連付けられた URL のリストを記述します。上記の HTML スニペットでは、/page-a/page-b をプリフェッチするようにブラウザに指示されています。<link rel="prefetch"> と同様に、推測ルールは、特定の状況でブラウザが無視するヒントです。

Quicklink などのライブラリは、ユーザーのビューポート内に表示されたページへのリンクを動的にプリフェッチまたは事前レンダリングすることで、ページ ナビゲーションを改善します。そうすれば、ページ上のすべてのリンクをプリフェッチするのではなく、ユーザーが最終的にそのページに移動する可能性が高まります。

ページを事前レンダリングする

リソースをプリフェッチするだけでなく、ユーザーが移動する前にページを事前レンダリングすることをブラウザに伝えることもできます。これにより、ページとそのリソースがバックグラウンドで取得されて処理されるため、ほぼ瞬時にページ読み込みを行うことができます。ユーザーがそのページに移動すると、ページがフォアグラウンドに移動します。

事前レンダリングは、Speculation Rules API を介してサポートされます。

<script type="speculationrules">
{
  "prerender": [
    {
      "source": "list",
      "urls": ["/page-a", "page-b"]
    }
  ]
}
</script>

プリフェッチと事前レンダリングのデモ

Service Worker のプレキャッシュ

Service Worker を使用して、投機的にリソースをプリフェッチすることもできます。Service Worker のプリフェッチでは、Cache API を使用してリソースを取得して保存できます。これにより、ブラウザはネットワークを経由せずに Cache API を使用してリクエストを処理できます。Service Worker のプレキャッシュでは、キャッシュのみの戦略と呼ばれる非常に効果的な Service Worker のキャッシュ戦略が使用されます。Service Worker のキャッシュに格納されたリソースは、リクエスト時にほぼ瞬時に取得されるため、このパターンは非常に効率的です。

ページから Service Worker、キャッシュへの Service Worker のキャッシュ フローを示しています。
キャッシュのみの戦略では、Service Worker のインストール中にネットワークから有効なリソースのみが取得されます。インストール後にキャッシュされたリソースは、Service Worker のキャッシュからのみ取得されます。

Service Worker を使用してリソースを事前キャッシュするには、ワークボックスを使用します。ただし、独自のコードを記述して所定のファイルセットをキャッシュに保存することもできます。いずれにせよ、Service Worker を使用してリソースを事前キャッシュする場合は、Service Worker のインストール時に事前キャッシュが行われることを認識しておくことが重要です。インストール後、事前キャッシュされたリソースは、Service Worker が制御するウェブサイトのページで取得できます。

ワークボックスは、プリキャッシュ マニフェストを使用して、どのリソースを事前キャッシュするかを決定します。プリキャッシュ マニフェストは、プリキャッシュするリソースの「信頼できる情報源」として機能するファイルとバージョニング情報のリストです。

[{  
    url: 'script.ffaa4455.js',
    revision: null
}, {
    url: '/index.html',
    revision: '518747aa'
}]

上記のコードは、script.ffaa4455.js/index.html の 2 つのファイルを含むマニフェストの例です。リソースのファイル自体にバージョン情報が含まれている場合(ファイル ハッシュ)、ファイルはすでにバージョニングされているため、revision プロパティは null のままで構いません(上記のコードの script.ffaa4455.js リソースの ffaa4455 など)。バージョニングされていないリソースについては、ビルド時にリビジョンを生成できます。

設定が完了すると、Service Worker を使用して静的ページまたはそのサブリソースを事前キャッシュし、後続のページ ナビゲーションを高速化できます。

workbox.precaching.precacheAndRoute([
  '/styles/product-page.ac29.css',
  '/styles/product-page.39a1.js',
]);

たとえば、e コマースの商品リスティング ページでは、Service Worker を使用して商品の詳細ページのレンダリングに必要な CSS と JavaScript を事前キャッシュすることで、商品の詳細ページへの移動がはるかに速くなります。上記の例では、product-page.ac29.cssproduct-page.39a1.js が事前キャッシュされています。workbox-precachingprecacheAndRoute メソッドは、事前キャッシュされたリソースが必要なときに Service Worker API から取得されるようにするために必要なハンドラを自動的に登録します。

Service Worker は広くサポートされているため、状況によっては、最新のブラウザで Service Worker のプレキャッシュを使用できます。

知識を試す

prefetch ヒントはどの優先度で発生しますか?

高。
もう一度お試しください。
中程度。
もう一度お試しください。
低。
正解です。

ページの事前取得と事前レンダリングの違いは何ですか?

ページのプリフェッチと事前レンダリングはどちらもページとそのすべてのサブリソースを取得しますが、プリフェッチはページとそのすべてのリソースを取得するだけであるのに対し、事前レンダリングはユーザーが移動するまでページ全体を背景にレンダリングすることでさらに一歩進んでいます。
正解です。
ほとんど同じです。事前レンダリングはページのすべてのサブリソースを取得しますが、プリフェッチは取得しません。
もう一度お試しください。

Service Worker のキャッシュと HTTP キャッシュは同じです。

正しい
もう一度お試しください。
False
正解です。

次のトピック: ウェブワーカーの概要

プリフェッチ、事前レンダリング、Service Worker の事前キャッシュが、将来のページへのナビゲーションを高速化するうえでどのように役立つかを理解しました。ここからは、これがウェブサイトとユーザーにとってどれほど有益であるかについて、知識に基づいて決定を下すことができるはずです。

次に、ウェブワーカーの概要と、ウェブワーカーがメインスレッドから負荷の大きい処理を取り除き、メインスレッドがユーザー操作のために余裕を持たせる方法について説明します。メインスレッドに余裕を持たせるために何ができるのか考えたことがある方は、次の 2 つのモジュールを試してみる価値があります。