この Codelab では、React SPA のデモに Quicklink ライブラリを実装し、プリフェッチによって後続のナビゲーションがいかに高速化されるかを示す方法を示します。
測定
最適化を追加する前に、まずアプリケーションの現在の状態を分析することをおすすめします。
- [Remix to Edit] をクリックして、プロジェクトを編集可能にします。
- サイトをプレビューするには、[アプリを表示] を押します。[ 全画面表示 。
このウェブサイトは、create-react-app で構築されたシンプルなデモです。
開いた新しいタブで、次の手順を行います。
- Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
- [ネットワーク] タブをクリックします。
- [キャッシュを無効にする] チェックボックスをオンにします。
- [Throttling] プルダウン リストで [Fast 3G] を選択して、低速の接続タイプをシミュレートします。
- アプリを再読み込みします。
- [フィルタ] テキスト ボックスに「
chunk
」と入力して、名前にchunk
を含まないリソースを非表示にします。
このサイトではルートベースのコード分割が使用されているため、最初に必要なコードのみがリクエストされます。
- DevTools でネットワーク リクエストをクリアします。
- アプリ内の [ブログ] リンクをクリックして、そのページに移動します。
新しいルートの JavaScript チャンクと CSS チャンクが読み込まれ、ページがレンダリングされます。
次に、このサイト内に Quicklink を実装して、これらのチャンクをホームページでプリフェッチできるようにし、ナビゲーションを高速化します。
これにより、両方の手法の長所を組み合わせることができます。
- ルートに基づいてコード分割を行うと、ブラウザはページの読み込み時に、必要なチャンクのみを高い優先度で読み込むように指示できます。
- プリフェッチはブラウザのアイドル時間に、ビューポート内のリンクのチャンクを最も低い優先度で読み込むようにブラウザに指示します。
webpack-route-manifest
の設定
まず、webpack-route-manifest をインストールして構成します。この Webpack プラグインを使用すると、ルートを対応するチャンクに関連付けるマニフェスト ファイルを生成できます。
通常はライブラリをインストールする必要がありますが、すでにインストールされています。次のコマンドを実行する必要があります。
npm install webpack-route-manifest --save-dev
config-overrides.js
はプロジェクトのルート ディレクトリに配置されたファイルで、プロジェクトを排除することなく、webpack 設定の既存の動作をオーバーライドできます。
- ソースを表示するには、[View Source] を押します。
config-overrides.js
を編集用に開き、ファイルの先頭に webpack-route-manifest
依存関係を追加します。
const path = require('path');
const RouteManifest = require('webpack-route-manifest');
次に、以下を追加して webpack-route-manifest
プラグインを構成します。
config-overrides.js
の末尾に追加します。
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
変数宣言の後に options
オブジェクトを作成し、quicklink
を呼び出すときに引数として使用します。
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 つのステップを繰り返します。まだブログページに移動しないでください。
ホームページが読み込まれると、そのルートのチャンクが読み込まれます。その後、Quicklink はビューポート内のリンクのルートのチャンクをプリフェッチします。
これらのチャンクは、ページをブロックすることなく、最も低い優先度でリクエストされます。
次のステップ:
- ネットワーク ログをもう一度消去します。
- [キャッシュを無効にする] チェックボックスをオフにします。
- [ブログ] をクリックして、そのページに移動します。
[Size] 列は、これらのチャンクがネットワークではなく「プリフェッチ キャッシュ」から取得されたことを示します。クイックリンクを使用せずにこれらのチャンクを読み込むには、約 580 ミリ秒かかりました。ライブラリを使用した場合、2 ミリ秒になりました。これは 99% の削減に相当します。