プリフェッチ、事前レンダリング、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-precaching で利用可能な precacheAndRoute メソッドは、事前キャッシュされたリソースが必要なときに Service Worker API からフェッチされるように必要なハンドラを自動的に登録します。

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

理解度テスト

prefetch ヒントはどの優先度で発生するか。

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

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

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

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

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

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

今後のページへの移動を高速化するうえで、プリフェッチ、事前レンダリング、Service Worker のプレキャッシュがいかに有益であるかを理解したところで、これがウェブサイトやそのユーザーにとってどれほど有益であるかについて、知識に基づいて決定を下せるはずです。

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