webpack学习笔记(14)-高级篇(5)-优化代码运行性能篇(2)
1. Preload
& Prefetch
为什么需要Preload
& Prefetch
- 我们前面已经做了代码分割,同时会使用
import
动态导入语法来进行代码按需加载(我们也叫懒加载,比如路由懒加载就是这样实现的)。 - 但是加载速度还不够好,比如:是用户点击按钮时才加载这个资源的,如果资源体积很大,那么用户会感觉到明显卡顿效果。
- 我们想在浏览器空闲时间,加载后续需要使用的资源。我们就需要用上
Preload
或Prefetch
技术。
什么是Preload
& Prefetch
Preload
:告诉浏览器立即加载资源。Prefetch
:告诉浏览器在空闲时才开始加载资源。
两者的共同点
- 都只会加载资源,并不执行。
- 都有缓存。
两者的不同点
Preload
加载优先级高,Prefetch
加载优先级低。Preload
只能加载当前页面需要使用的资源,Prefetch
可以加载当前页面资源,也可以加载下一个页面需要使用的资源。
总结:
- 当前页面优先级高的资源用
Preload
加载。 - 下一个页面需要使用的资源用
Prefetch
加载。
它们的问题:兼容性较差。
- 我们可以去 Can I Use 网站查询 API 的兼容性问题。
Preload
相对于Prefetch
兼容性好一点。
官方网站
基本使用
- 下载包
npm i @vue/preload-webpack-plugin -D |
- 配置
webpack.prod.js
// 使用的是commonjs 的语法格式[node.js] |
结果展示:(这里展示preload
,prefetch
基本一致)
输出的
html
模板在浏览器开发工具中可以看到,浏览器一刷新,
sayhi.js
就加载了
2. Core-js
为什么需要Core-js
?
- 过去我们使用
babel
对js
代码进行了兼容性处理,其中使用@babel/preset-env
智能预设来处理兼容性问题。 - 它能将
ES6
的一些语法进行编译转换,比如箭头函数、点点点运算符等。但是如果是async
函数、promise
对象、数组的一些方法(includes
)等,它没办法处理。 - 所以此时我们
js
代码仍然存在兼容性问题,一旦遇到低版本浏览器会直接报错。所以我们想要将js
兼容性问题彻底解决
什么是Core-js
core-js
是专门用来做 ES6 以及以上 API 的polyfill
。polyfill
翻译过来叫做垫片/补丁。就是用社区上提供的一段代码,让我们在不兼容某些新特性的浏览器上,使用该新特性。
基本使用
- 修改
main.js
(添加es7
新语法(includes
))
// 引入js文件 |
- 此时
Eslint
会对includes
报错。
修改配置文件
- 下载包
npm i @babel/eslint-parser -D
- 创建
.eslintrc.js
module.exports = {
// 继承 Eslint 规则
extends: ["eslint:recommended"],
parser: "@babel/eslint-parser", // 支持最新的最终 ECMAScript 标准
env: {
node: true, // 启用node中全局变量
browser: true, // 启用浏览器中全局变量
},
plugins: ["import"], // 解决动态导入import语法报错问题 --> 实际使用eslint-plugin-import的规则解决的
parserOptions: {
ecmaVersion: 6, // es6
sourceType: "module", // es module
},
rules: {
"no-var": 2, // 不能使用 var 定义变量
},
};使用
core-js
- 下载包
npm i core-js |
- 方法一: 手动全部引入(优点:方便快捷 , 缺点:打包生成的项目体积大)
// 全部引入 core.js |
- 方法二: 手动按需引入(优点:项目体积小 , 缺点: 引入繁琐)
// 全部引入 core.js |
自动按需引入(推荐使用)
这种方法不需要在
main.js
中引入core.js
,我们只需要在babel.config.js
中的presets
属性中设置相关项即可
babel.config.js
module.exports = { |
- 此时就会自动根据我们代码中使用的语法,来按需加载相应的
polyfill
了。
3. PWA
为什么需要PWA
- 开发
Web App
项目,项目一旦处于网络离线情况,就没法访问了。 - 我们希望给项目提供离线体验。
PWA
是什么?
渐进式网络应用程序(
progressive web application - PWA
):是一种可以提供类似于native app
(原生应用程序) 体验的Web App
的技术。其中最重要的是,在
离线(offline)
时应用程序能够继续运行功能。内部通过
Service Workers
技术实现的。
如何使用
- 下载包
npm i workbox-webpack-plugin -D |
- 修改配置文件
// 使用的是commonjs 的语法格式[node.js] |
- 修改
main.js
// 全部引入 core.js |
- 运行指令
npm run build |
此时如果通过 VSCode 访问打包后页面,在浏览器控制台出现 SW registration failed
。
因为我们打开的访问路径是:
http://127.0.0.1:5500/dist/index.html
。此时页面会去请求service-worker.js
文件,请求路径是:http://127.0.0.1:5500/service-worker.js
,这样找不到会 404。实际
service-worker.js
文件路径是:http://127.0.0.1:5500/dist/service-worker.js
。
- 解决路径问题
- 下载包
npm i serve -g |
serve
也是用来启动开发服务器来部署代码查看效果的。
- 运行指令
serve dist |
此时通过 serve
启动的服务器我们 service-worker
就能注册成功了。
结果展示:(离线后仍然可以进行基本输出)
webpack
高级篇总结
我们从 4 个角度对 webpack
和代码进行了优化:
- 提升开发体验
- 使用
Source Map
让开发或上线时代码报错能有更加准确的错误提示。
- 提升 webpack 提升打包构建速度
- 使用
HotModuleReplacement
让开发时只重新编译打包更新变化了的代码,不变的代码使用缓存,从而使更新速度更快。 - 使用
OneOf
让资源文件一旦被某个 loader 处理了,就不会继续遍历了,打包速度更快。 - 使用
Include/Exclude
排除或只检测某些文件,处理的文件更少,速度更快。 - 使用
Cache
对 eslint 和 babel 处理的结果进行缓存,让第二次打包速度更快。 - 使用
Thead
多进程处理 eslint 和 babel 任务,速度更快。(需要注意的是,进程启动通信都有开销的,要在比较多代码处理时使用才有效果)
- 减少代码体积
- 使用
Tree Shaking
剔除了没有使用的多余代码,让代码体积更小。 - 使用
@babel/plugin-transform-runtime
插件对 babel 进行处理,让辅助代码从中引入,而不是每个文件都生成辅助代码,从而体积更小。 - 使用
Image Minimizer
对项目中图片进行压缩,体积更小,请求速度更快。(需要注意的是,如果项目中图片都是在线链接,那么就不需要了。本地项目静态图片才需要进行压缩。)
- 优化代码运行性能
- 使用
Code Split
对代码进行分割成多个 js 文件,从而使单个文件体积更小,并行加载 js 速度更快。并通过 import 动态导入语法进行按需加载,从而达到需要使用时才加载该资源,不用时不加载资源。 - 使用
Preload / Prefetch
对代码进行提前加载,等未来需要使用时就能直接使用,从而用户体验更好。 - 使用
Network Cache
能对输出资源文件进行更好的命名,将来好做缓存,从而用户体验更好。 - 使用
Core-js
对 js 进行兼容性处理,让我们代码能运行在低版本浏览器。 - 使用
PWA
能让代码离线也能访问,从而提升用户体验。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0许可协议。转载请注明来自 肥林の仓库