此 Codelab 将介绍如何在 React SPA 演示中实现 Quicklink 库,以演示预提取如何加快后续导航的速度。
测量
在添加优化之前,最好先分析应用的当前状态。
- 点击 Remix to Edit 以使项目可修改。
- 如需预览网站,请按查看应用。然后按 全屏 。
该网站是一个使用 create-react-app 构建的简单演示。
在刚刚打开的新标签页中,按照以下说明操作:
- 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
- 点击网络标签页。
- 选中停用缓存复选框。
- 在限制下拉列表中,选择 Fast 3G 以模拟慢速连接类型。
- 重新加载应用。
- 在过滤器文本框中输入
chunk
可隐藏名称中不包含chunk
的所有资源。
该网站使用基于路由的代码拆分,因此在开始时仅请求必要的代码。
- 在开发者工具中清除网络请求。
- 在应用中,点击博客链接即可前往该页面。
系统会加载新路线的 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');
接下来,通过添加以下代码来配置 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% 缩短了!