この Codelab では、React SPA のデモで Quicklink ライブラリを実装し、プリフェッチによって後続のナビゲーションがどのように高速化されるかを説明します。
測定
最適化を追加する前に、まずアプリケーションの現在の状態を分析することをおすすめします。
- [Remix to Edit] をクリックしてプロジェクトを編集可能にします。
- サイトをプレビューするには、[アプリを表示] を押してから、全画面表示 を押します。
ウェブサイトは、create-react-app で構築されたシンプルなデモです。
開いた新しいタブで、次の手順を行います。
- Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
- [Network] タブをクリックします。
- [キャッシュを無効にする] チェックボックスをオンにします。
- [Throttling] プルダウン リストで [Fast 3G] を選択して、低速な接続タイプをシミュレートします。
- アプリを再読み込みします。
- [フィルタ テキスト] に「
chunk
」と入力して、名前にchunk
を含まないリソースを非表示にします。
このサイトではルートベースのコード分割を使用しているため、最初に必要なコードのみがリクエストされます。
- DevTools でネットワーク リクエストを消去します。
- アプリ内で、[ブログ] リンクをクリックしてそのページに移動します。
新しいルートの JS チャンクと CSS チャンクが読み込まれて、ページがレンダリングされます。
次に、このサイトに Quicklink を実装して、これらのチャンクをホームページでプリフェッチして、ナビゲーションを高速化できるようにします。
これにより、両方の手法の長所を組み合わせることができます。
- ルートベースのコード分割では、ページの読み込み時に高い優先度で必要なチャンクのみを読み込むようにブラウザに指示します。
- プリフェッチは、ブラウザのアイドル時間中に、ビューポート内のリンクのチャンクを最も低い優先度で読み込むようにブラウザに指示します。
webpack-route-manifest
を設定
まず、webpack-route-manifest をインストールして構成します。webpack プラグインを使用すると、ルートを対応するチャンクに関連付けるマニフェスト ファイルを生成できます。
通常はライブラリのインストールが必要ですが、すでにインストール済みです。実行する必要があるコマンドは次のとおりです。
npm install webpack-route-manifest --save-dev
config-overrides.js
はプロジェクトのルート ディレクトリにあるファイルです。このファイルでは、プロジェクトを削除することなく、webpack 構成の既存の動作をオーバーライドできます。
- ソースを表示するには、[ソースを表示] を押します。
config-overrides.js
を開いて編集し、ファイルの先頭に webpack-route-manifest
依存関係を追加します。
const path = require('path');
const RouteManifest = require('webpack-route-manifest');
次に、config-overrides.js
の下部に次のコードを追加して、webpack-route-manifest
プラグインを構成します。
module.exports = function override(config) {
config.resolve = {
...config.resolve,
alias: {
'@assets': `${path.resolve(__dirname, 'src/assets')}`,
'@pages': `${path.resolve(__dirname, 'src/pages')}`,
'@components': `${path.resolve(__dirname, 'src/components')}`,
},
};
config.plugins.push(
new RouteManifest({
minify: true,
filename: 'rmanifest.json',
routes(str) {
let out = str.replace('@pages', '').toLowerCase();
if (out === '/article') return '/blog/:title';
if (out === '/home') return '/';
return out;
},
}),
);
return config;
};
新しいコードは次の処理を行います。
config.resolve
は、ページ、アセット、コンポーネントへの内部ルートを含む変数を宣言します。config.plugins.push()
はRouteManifest
オブジェクトを作成して構成を渡します。これにより、サイトのルートとチャンクに基づいてrmanifest.json
ファイルを生成できます。
manifest.json
ファイルが生成され、https://site_url/rmanifest.json
で利用できるようになります。
クイックリンクを設定
この時点で、プロジェクトに Quicklink ライブラリをインストールする必要があります。わかりやすくするため、すでにプロジェクトに追加されています。実行する必要があるコマンドは次のとおりです。
npm install --save quicklink
src/components/App/index.js
を開いて編集します。
まず、Quicklink 高注文コンポーネント(HOC)をインポートします。
import React, { lazy, Suspense } from 'react';
import { Route } from 'react-router-dom';
import Footer from '@components/Footer';
import Hero from '@components/Hero';
import style from './index.module.css';
import { withQuicklink } from 'quicklink/dist/react/hoc.js';
const Home = lazy(() => import(/* webpackChunkName: "home" */ '@pages/Home'));
const About = lazy(() => import(/* webpackChunkName: "about" */ '@pages/About'));
const Article = lazy(() => import(/* webpackChunkName: "article" */ '@pages/Article'));
const Blog = lazy(() => import(/* webpackChunkName: "blog" */ '@pages/Blog'));
次に、Blog
変数宣言の後に、quicklink
を呼び出すときに引数として使用する options
オブジェクトを作成します。
const options = {
origins: []
};
最後に、各ルートを高階コンポーネント withQuicklink()
でラップし、options
パラメータとそのルートのターゲット コンポーネントを渡します。
const App = () => (
<div className={style.app}>
<Hero />
<main className={style.wrapper}>
<Suspense fallback={<div>Loading...</div>}>
<Route path="/" exact component={withQuicklink(Home, options)} />
<Route path="/blog" exact component={withQuicklink(Blog, options)} />
<Route
path="/blog/:title"
component={withQuicklink(Article, options)}
/>
<Route path="/about" exact component={withQuicklink(About, options)} />
</Suspense>
</main>
<Footer />
</div>
);
上記のコードは、リンクがビューに到達したときに、withQuicklink()
でラップされたルートのチャンクをプリフェッチするよう指示しています。
再測定
「測定」の最初の 6 つのステップを繰り返します。まだブログページに移動しないでください。
ホームページがそのルートのチャンクを読み込むと、その後、クイックリンクはビューポート内リンクのルートのチャンクをプリフェッチします。
これらのチャンクは、ページをブロックせずに、最も低い優先度でリクエストされます。
次のステップ:
- ネットワーク ログを再度クリアします。
- [キャッシュを無効にする] チェックボックスをオフにします。
- [ブログ] リンクをクリックして、そのページに移動します。
[Size] 列は、これらのチャンクがネットワークではなく「プリフェッチ キャッシュ」から取得されたことを示します。クイックリンクを使用せずにこれらのチャンクの読み込みには、約 580 ミリ秒かかりました。ライブラリを使用した場合、所要時間は 2 ミリ秒になりました。これは 99% 削減に相当します。