大多数网页和应用均由许多不同的部分组成。而不是 系统会尽快发送构成应用的所有 JavaScript, 网页在加载后将 JavaScript 分成多个块 提高网页性能。
此 Codelab 介绍了如何使用代码拆分来提高 对三个数字进行排序的简单应用。
测量
与往常一样,必须先衡量网站的效果 尝试添加任何优化措施
- 如需预览网站,请按查看应用。然后按 全屏 。
- 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
- 点击网络标签页。
- 选中停用缓存复选框。
- 重新加载应用。
只是为了对一个简单应用中的几个数字进行排序,实际需要花费 71.2 KB 的 JavaScript 代码。 这是怎么回事?
在源代码 (src/index.js
) 中,导入并使用 lodash
库
应用。Lodash 提供了许多实用的实用程序
函数,但这里只使用 包中的一个方法。
安装并导入整个第三方依赖项,其中只有一个
但有一部分被利用都是比较常见的错误。
优化
您可以通过以下几种方式来缩减 bundle 大小:
- 编写自定义排序方法,而不是导入第三方库
- 使用内置的
Array.prototype.sort()
方法按数字排序 - 仅从
lodash
导入sortBy
方法,而非整个库 - 仅在用户点击按钮时下载用于排序的代码
方法 1 和方法 2 是缩减 bundle 大小(并且 可能最适合实际应用的情况)。但这些是 本教程中未用到的一些功能,只是供教 😈? 时使用。
选项 3 和选项 4 都有助于提高此应用的性能。通过 在此 Codelab 的后面几个部分中,我们将介绍这些步骤。就像编写任何代码 教程中,请始终尝试自行编写代码,而不是复制和粘贴。
仅导入您需要的内容
需要修改一些文件,以便仅从 lodash
导入单个方法。
首先,替换 package.json
中的以下依赖项:
"lodash": "^4.7.0",
替换为:
"lodash.sortby": "^4.7.0",
现在,在 src/index.js
中导入此特定模块:
import "./style.css";
import _ from "lodash";
import sortBy from "lodash.sortby";
然后更新值的排序方式:
form.addEventListener("submit", e => {
e.preventDefault();
const values = [input1.valueAsNumber, input2.valueAsNumber, input3.valueAsNumber];
const sortedValues = _.sortBy(values);
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
});
重新加载应用,打开开发者工具,然后查看 Network 面板 。
对于此应用,其软件包大小缩减了 4 倍多,且 但仍有改进的空间。
代码拆分
webpack 是最受欢迎的开源软件之一 当前使用的模块打包器简而言之,它捆绑了所有 JavaScript 模块(作为 以及将组成 Web 应用的静态文件 供浏览器读取
此应用中使用的单个软件包可拆分为两个单独的软件包 数据块:
- 负责组成初始路由的代码
- 包含排序代码的次要数据块
通过使用动态导入,可以延迟加载辅助分块,或者 按需加载。在此应用中,构成数据块的代码可以是 仅在用户按下该按钮时加载。
首先,移除 src/index.js
中排序方法的顶级导入项:
import sortBy from "lodash.sortby";
然后将其导入到按下按钮时触发的事件监听器中:
form.addEventListener("submit", e => {
e.preventDefault();
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
import()
功能是
提案(目前处于阶段
TC39 流程中的 3 部分)添加动态导入模块的功能。
webpack 已包含对此项的支持,并遵循
被提案取消
import()
返回一个 promise,在解析后,选定的
模块中将该模块拆分为一个单独的块。完成本单元的学习后
module.default
用于引用默认的
即 lodash 提供的导出内容。promise 与另一个 .then
链接,
调用 sortInput
方法来对三个输入值进行排序。在
promise 链。catch()
用于处理 promise 被拒绝的情况
发生错误。
需要完成的最后一项任务是在sortInput
。该函数必须是返回
接受从 lodash.sortBy
导入的方法。然后,嵌套函数
对三个输入值进行排序并更新 DOM。
const sortInput = () => {
return (sortBy) => {
const values = [
input1.valueAsNumber,
input2.valueAsNumber,
input3.valueAsNumber
];
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
};
}
监控
最后一次重新加载应用,并密切关注网络 面板。应用一经运行,便只会下载一个小的初始 bundle 。
按下按钮对输入数字进行排序后,包含 系统会提取并执行排序代码
请注意数据是如何排序的!
总结
代码拆分和延迟加载是精简代码 应用的初始 bundle 大小,这直接导致 网页加载速度会快得多不过,您需要注意一些重要事项 在向应用添加此优化之前要考虑的因素。
延迟加载界面
延迟加载特定代码模块时,请务必考虑 将改善用户体验拆分和 在用户提交操作时加载一大段代码会使 该应用似乎已停止运行,因此请考虑显示 某种加载指示器
延迟加载第三方节点模块
在
这取决于您的使用位置。通常,第三方
依赖项会拆分为单独的 vendor
bundle,该 bundle 可以进行缓存,
它们的更新频率较低。详细了解
SplitChunksPlugin 可以
可以帮助您实现这一目标。
使用 JavaScript 框架实现延迟加载
许多使用 Webpack 的常用框架和库都为 相较于在开发应用时使用动态导入 应用。
虽然了解动态导入的工作原理很有帮助,但始终使用 方法(由框架/库推荐的方法来延迟加载特定模块)。
预加载和预提取
请尽可能利用浏览器提示,例如 <link rel="preload">
或 <link rel="prefetch">
,以尝试加载关键模块,甚至
加快实施速度。webpack 通过在导入中使用魔术注释来支持这两种提示
语句。有关详情,请参阅
预加载关键分块指南。
延迟加载不仅仅是代码
图像可以构成应用的重要组成部分。延迟加载 非首屏或设备视口外),都可以加快网站的加载速度。已读 请参阅 Lazysizes 指南。