この Codelab では、<link rel="prefetch">
と HTTP Link
ヘッダーの 2 つの方法でプリフェッチを実装します。
このサンプルアプリは、プロモーションのランディング ページとして、そのショップのベストセラーの T シャツの特別割引を提供するウェブサイトです。ランディング ページは 1 つの商品にリンクされているため、商品の詳細ページに移動するユーザーの割合は高いと想定しても安全です。そのため、商品ページはランディング ページでプリフェッチする候補として有用です。
パフォーマンスの測定
まず、ベースライン パフォーマンスを確立します。
- [Remix to Edit] をクリックしてプロジェクトを編集可能にします。
- サイトをプレビューするには、[アプリを表示] を押してから、全画面表示 を押します。
- Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
[Network] タブをクリックします。
[Throttling] プルダウン リストで [Fast 3G] を選択して、低速な接続タイプをシミュレートします。
商品ページを読み込むには、サンプルアプリで [Buy now] をクリックします。
product-details.html
ページの読み込みには約 600 ミリ秒かかります。
<link rel="prefetch">
で商品ページをプリフェッチする
ナビゲーションを改善するには、ランディング ページに prefetch
タグを挿入して product-details.html
ページをプリフェッチします。
views/index.html
ファイルのヘッダーに次の<link>
要素を追加します。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
as
属性は省略可能ですが、指定することをおすすめします。この属性を指定することで、ブラウザが適切なヘッダーを設定し、リソースがすでにキャッシュに存在するかどうかを判断できます。この属性の値の例: document
、script
、style
、font
、image
、その他。
プリフェッチが機能していることを確認するには:
- サイトをプレビューするには、[アプリを表示] を押してから、全画面表示 を押します。
- Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
[Network] タブをクリックします。
[Throttling] プルダウン リストで [Fast 3G] を選択して、低速な接続タイプをシミュレートします。
[キャッシュを無効にする] チェックボックスをオフにします。
アプリを再読み込みします。
これで、ランディング ページが読み込まれるときに product-details.html
ページも読み込まれるようになりますが、優先度は最も低くなります。
ページは HTTP キャッシュに 5 分間保持されます。その後は、ドキュメントの通常の Cache-Control
ルールが適用されます。この例では、product-details.html
に public, max-age=0
の値を持つ cache-control
ヘッダーがあります。これは、ページが合計 5 分間保持されることを意味します。
パフォーマンスを再評価する
- アプリを再読み込みします。
- 商品ページを読み込むには、サンプルアプリで [Buy now] をクリックします。
[ネットワーク] パネルを確認します。最初のネットワーク トレースとの違いは 2 つあります。
- [Size] 列には「プリフェッチ キャッシュ」と表示されています。これは、このリソースがネットワークではなくブラウザのキャッシュから取得されたことを意味します。
- [時間] 列に、ドキュメントの読み込みにかかる時間が約 10 ミリ秒になったことが示されます。
約 600 ミリ秒かかっていた以前のバージョンと比較すると、約 98% 短縮されています。
追加の実習: prefetch
を段階的な機能強化として活用する
プリフェッチは、高速な接続でブラウジングするユーザー向けに段階的な機能強化として実装するのが最も効果的です。Network Information API を使用すると、ネットワーク状態を確認し、それに基づいてプリフェッチ タグを動的に挿入できます。これにより、データ消費を最小限に抑え、低速または高額のデータプランのユーザーの費用を削減できます。
適応型プリフェッチを実装するには、まず views/index.html
から <link rel="prefetch">
タグを削除します。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
次に、以下のコードを public/script.js
に追加して、ユーザーが高速接続を利用しているときに prefetch
タグを動的に挿入する関数を宣言します。
function injectLinkPrefetchIn4g(url) {
if (window.navigator.connection.effectiveType === '4g') {
//generate link prefetch tag
const linkTag = document.createElement('link');
linkTag.rel = 'prefetch';
linkTag.href = url;
linkTag.as = 'document';
//inject tag in the head of the document
document.head.appendChild(linkTag);
}
}
この関数は次のように動作します。
- この関数は Network Information API の effectiveType プロパティをチェックして、ユーザーが 4G(またはそれより高速な)接続を使用しているかどうかを判断します。
- この条件が満たされると、ヒントのタイプとして
prefetch
を持つ<link>
タグを生成し、プリフェッチされる URL をhref
属性で渡し、リソースがas
属性の HTMLdocument
であることを示します。 - 最後に、スクリプトをページの
head
に動的に追加します。
次に、views/index.html
の </body>
終了タグの直前に script.js
を追加します。
<body>
...
<script src="/script.js"></script>
</body>
ページの最後で script.js
をリクエストすると、ページの解析と読み込みの完了後に読み込み、実行されます。
プリフェッチによって現在のページの重要なリソースが妨げられないようにするには、次のコード スニペットを追加して、window.load
イベントで injectLinkPrefetchIn4g()
を呼び出します。
<body>
...
<script src="/script.js"></script>
<script>
window.addEventListener('load', () => {
injectLinkPrefetchIn4g('/product-details.html');
});
</script>
</body>
ランディング ページは、高速接続の場合にのみ product-details.html
をプリフェッチするようになりました。確認する手順は次のとおりです。
- サイトをプレビューするには、[アプリを表示] を押してから、全画面表示 を押します。
- Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
- [Network] タブをクリックします。
- [スロットリング] プルダウン リストで [オンライン] を選択します。
- アプリを再読み込みします。
[Network] パネルに product-details.html
が表示されます。
接続速度が遅い場合に商品ページがプリフェッチされないことを確認する手順は次のとおりです。
- [Thottling] プルダウン リストで [Slow 3G] を選択します。
- アプリを再読み込みします。
[ネットワーク] パネルには、product-details.html
のないランディング ページのリソースのみが表示されます。
HTTP Link
ヘッダーを使用して商品ページのスタイルシートをプリフェッチする
HTTP Link
ヘッダーは、link
タグと同じタイプのリソースをプリフェッチするために使用できます。パフォーマンスの違いはそれほどないため、どちらを使用するべきかは、主にユーザーの好みによって決まります。今回は、商品ページのメインの CSS をプリフェッチしてレンダリングをさらに改善します。
ランディング ページのサーバー レスポンスに、style-product.css
の HTTP Link
ヘッダーを追加します。
server.js
ファイルを開き、ルート URL(/
)のget()
ハンドラを探します。- ハンドラの先頭に次の行を追加します。
app.get('/', function(request, response) {
response.set('Link', '</style-product.css>; rel=prefetch');
response.sendFile(__dirname + '/views/index.html');
});
- サイトをプレビューするには、[アプリを表示] を押してから、全画面表示 を押します。
- Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
- [Network] タブをクリックします。
- アプリを再読み込みします。
ランディング ページが読み込まれた後に、style-product.css
が最も低い優先度でプリフェッチされるようになりました。
商品ページに移動するには、[今すぐ購入] をクリックします。[Network] パネルを確認します。
style-product.css
ファイルは「プリフェッチ キャッシュ」から取得され、読み込みには 12 ミリ秒しかかからなかった。