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

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

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

これは少し難しいバランスです。使用されない可能性のあるリソースを読み込んで帯域幅を無駄にしたくはありませんが、インタラクションや後続のページ読み込みを遅らせるのも理想的ではありません。幸いなことに、この 2 つの極端な状況のバランスを改善するために使用できるツールがいくつかあります。このモジュールでは、リソースのプリフェッチ、ページ全体のプリレンダリング、サービス ワーカーを使用したリソースのプリキャッシュなど、そのための手法をいくつか紹介します。

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

<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 では、フラグの背後で利用できます。すべてのブラウザで動作する形でウェブサイトのリソースを先読みする必要性が高い場合で、サービス ワーカーを使用している場合は、このモジュールの後半のセクションで、サービス ワーカーを使用したリソースのプリキャッシュについてお読みください。

ページをプリフェッチして、今後のナビゲーションを高速化する

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 を使用して、リソースを投機的にプリフェッチすることもできます。サービス ワーカーのプリキャッシュでは、Cache API を使用してリソースを取得して保存できます。これにより、ブラウザはネットワークにアクセスせずに Cache API を使用してリクエストを処理できます。サービス ワーカーのプリキャッシュでは、キャッシュのみの戦略と呼ばれる非常に効果的なサービス ワーカーのキャッシュ保存戦略が使用されます。このパターンは、リソースがサービス ワーカー キャッシュに配置されると、リクエストに応じてほぼ瞬時に取得されるため、非常に効果的です。

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

サービス ワーカーを使用してリソースをプリキャッシュするには、Workbox を使用します。ただし、必要に応じて、独自のコードを記述して、あらかじめ決められた一連のファイルをキャッシュに保存することもできます。サービス ワーカーを使用してリソースをプリキャッシュする方法をどちらにするにしても、プリキャッシュはサービス ワーカーがインストールされたときに行われることを知っておくことが重要です。インストール後、プリキャッシュされたリソースは、ウェブサイト上の Service Worker が制御する任意のページで取得できるようになります。

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

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

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

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

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

たとえば、e コマースの商品リスティング ページでは、サービス ワーカーを使用して商品詳細ページのレンダリングに必要な CSS と JavaScript をプリキャッシュすることで、商品詳細ページへの移動を大幅に高速化できます。前の例では、product-page.ac29.cssproduct-page.39a1.js がプリキャッシュされます。workbox-precaching で利用可能な precacheAndRoute メソッドは、プリキャッシュされたリソースが必要なときにいつでも Service Worker API から取得されるようにするために必要なハンドラを自動的に登録します。

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

理解度テスト

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

高。
もう一度お試しください。
中。
もう一度お試しください。
ドライブ
正解です。

ページのプリフェッチとプリレンダリングの違いは何ですか?

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

サービス ワーカー キャッシュと HTTP キャッシュは同じです。

正しい
もう一度チャレンジしてください。
誤り
正解です。

次は、ウェブ ワーカーの概要について説明します。

プリフェッチ、プリレンダリング、サービス ワーカーのプリキャッシュが、今後のページへのナビゲーションを高速化するうえでどのように役立つかをご理解いただけたかと思います。これらを踏まえて、ウェブサイトとそのユーザーにとってのメリットを判断できるようになりました。

次に、ウェブ ワーカーの概要と、ウェブ ワーカーがコストのかかる作業をメインスレッドから取り除き、ユーザー インタラクションのためのメインスレッドの余裕を増やす方法について説明します。メインスレッドに余裕を持たせるために何ができるか疑問に思ったことがあるなら、次の 2 つのモジュールは必見です。