Vite 性能篇:掌握这些优化策略,一起纵享丝滑!
highlight: atom-one-dark theme: cyanosis
很多兄弟都在使用 Vite 了,但如果你是前端 leader 或者是团队核心的话,不得不可考虑的一个问题就是性能优化。Vite 在开发环境性能已经非常不错了,生产环境应该如何优化呢?其实优化方式和 Webpack 差不多,只不过 Vite 打包时用的是 Rollup 。那么还等什么,一起学起来!
分包策略
默认情况下,浏览器重复请求相同名称的静态资源时,会直接使用缓存的资源。利用这个机制我们可以将不会经常更新的代码单独打包成一个 JS 文件,这样就可以减少 HTTP 请求,同时降低服务器压力。以 lodash
为例:
js
npm i lodash
安装 lodash
,然后在 main.js
中写入以下代码:
```js // src/main.js import { cloneDeep } from 'lodash'
const obj = cloneDeep({}) ``` 打包结果:
项目代码和依赖模块打包成了一个 JS 文件。接着我们来配置分包,修改底层的 Rollup 配置:
```js // vite.config.js import { defineConfig } from 'vite'
export default defineConfig({ build: { rollupOptions: { output: { manualChunks: id => { // 将 node_modules 中的代码单独打包成一个 JS 文件 if(id.includes('node_modules')) { return 'vendor' } } } } } }) ```
打包结果如下:
可以看到依赖模块已经单独生成一个 JS 文件了。这样我们即使修改了 main.js
中的代码重新打包,依赖文件 vendor.528a7280.js
也不会发生变化的,对于这个文件,浏览器也不会再次发起请求。如果依赖模块很多的话,性能是不是有很大的提升呢?
treeshaking
treeshaking
也被称为 “摇树优化”。简单来讲,就是在保证代码运行结果不变的前提下,去除无用的代码。Vue3中,许多 ApI
的引入都支持 treeshaking
优化。也就是说只打包你用到的 API
,忽略那些没有用到的。
Vue3 会默认使用 Rollup 进行 treeshaking
,不需要额外进行配置。但有一个条件,必须是 ES6 module
模块才行。还是上面那个例子:
```js // src/main.js import { cloneDeep } from 'lodash'
const obj = cloneDeep({}) ```
由于 lodash 是使用 CommonJS
规范的模块,所以无法进行 treeshaking
,Vue 会把整个 lodash
依赖打包进来。整个依赖文件的大小是 78.64 KB
。
然后我们使用 ESM
版的 loadsh
对比一下:
js
npm i lodash-es
```js
// src/main.js
import { cloneDeep } from 'lodash-es'
const obj = cloneDeep({}) ``` 打包结果如下:
可以看到依赖体积瞬间变成了 13.23 KB
,是不是一下小了很多。所以我们在选择第三方库时,要尽可能使用 ESM
版本,可以提升不少性能!
gzip 压缩
gzip
是一种使用非常普遍的压缩格式。使用 gzip
压缩可以大幅减小代码体积,提升网络性能。开启 gzip
也比较简单,使用一个插件就可以了:
js
npm i vite-plugin-compression
```js // vite.config.js import { defineConfig } from 'vite' import viteCompression from 'vite-plugin-compression'
export default defineConfig({ plugins: [viteCompression()] }) ``` 打包结果如下:
可以看到经过 gzip
压缩后,vendor.6fd516d3.js
文件从 13.23 KB
降到了 4.62KB
,文件体积缩小了近 2/3 ,是不是很 nice。接下来就是后端同学的工作了:当请求静态资源时,如果发现有对应的 gzip 的文件,直接把 gzip 内容返给前端,并且设置一个响应头 content-encoding: gzip
。
完整逻辑是,我们需要把浏览器支持的压缩类型传给服务端,在请求头中设置 accept-encoding: gzip, deflate, br
,只不过这一步浏览器通常帮我们都做了。然后服务端根据浏览器支持的类型,设置响应头 content-encoding: gzip
,告诉浏览器以何种方式进行解压。
注意:因为浏览器解压也需要时间,所以代码体积不是很大的话不建议使用 gzip
压缩。
cdn 加速
内容分发网络(Content Delivery Network,简称 CDN)就是让用户从最近的服务器请求资源,提升网络请求的响应速度。通常我们请求依赖模块使用 CDN ,而请求项目代码依然使用自己的服务器。还是以 lodash
为例:
```js // src/main.js import _ from 'lodash'
const obj = _.cloneDeep({}) ```
使用 CDN 也比较简单,一个插件就可以搞定:
js
npm i vite-plugin-cdn-import -D
```js // vite.config.js import { defineConfig } from 'vite' import viteCDNPlugin from 'vite-plugin-cdn-import'
export default defineConfig({
plugins: [
viteCDNPlugin({
// 需要 CDN 加速的模块
modules: [
{
name: 'lodash',
var: '_',
path: https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js
}
]
})
]
})
``
构建成功后,Vite 会自动帮我们将 cdn 资源通过
script标签插入到
html` 中:
这样请求 lodash
资源就会产生加速 buff
,而且项目体积也会大大减小!
图片压缩
根据项目对清晰度的要求,我们可以使用 vite-plugin-imagemin
插件,对图片进行适当压缩:
js
npm i vite-plugin-imagemin -D
```js // vite.config.js import { defineConfig } from 'vite' import viteImagemin from 'vite-plugin-imagemin'
export default defineConfig({ plugins: [ viteImagemin({ gifsicle: { optimizationLevel: 7, interlaced: false }, optipng: { optimizationLevel: 7 }, mozjpeg: { quality: 20 }, pngquant: { quality: [0.8, 0.9], speed: 4 }, svgo: { plugins: [ { name: 'removeViewBox' }, { name: 'removeEmptyAttrs', active: false } ] } }) ] }) ``` 不同格式的文件配置也不一样,具体可以参考 github :vite-plugin-imagemin 。
构建分析
分析依赖模块的大小占比,可以让我们更有针对性的进行体积优化。我们通常使用 rollup-plugin-visualizer
插件进行构建分析,方法也比较简单:
js
npm install rollup-plugin-visualizer -D
```js // vite.config.js import { defineConfig } from 'vite' import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
// 将 visualizer 插件放到最后
visualizer()
]
})
``
npm run build,构建成功之后会在根目录下生成一个
stats.html,打开页面即可以看到分析结果。我们还可以通过左上角的
排除、
包含` 输入框对依赖模块进行筛选。同时鼠标移入各模块,可以看到详细的分析数据:
小结
ok,今天的分享就是这些。如果你的项目已经在用 Vite ,不妨试验一下以上方案,看看项目会不会变得更加丝滑。又到年底了,今年能挺过来的都不容易。最后祝大家都能拿到满意的年终奖~😋
- Vite 性能篇:掌握这些优化策略,一起纵享丝滑!
- Vite 配置篇:日常开发掌握这些配置就够了!
- Vite 入门篇:学会它,一起提升开发幸福感!
- 还有人没尝过 Pinia 吗,请收下这份食用指南!
- 10个常见的使用场景,助你从 Vue2 丝滑过渡到 Vue3 !
- 前端手写功能第二弹,提升内力,等待下一次爆发!
- 效率提升之 —— 如何优雅的带走上份工作的VSCode配置
- Vue组件递归——组件化开发的必备技能!
- 10个常用的JS工具库,80%的项目都在用!
- 如何严格判断文件上传类型?再不会你就out啦!
- Element-UI 奇淫技巧第二弹!提升开发效率,延长摸鱼时间~
- 原来虚拟列表如此简单!万万没想到
- 10个常见的前端手写功能,你全都会吗?
- 一款强大到没朋友的图片编辑插件,爱了爱了!
- 如何实现拖拽上传、上传进度条,以及取消上传?
- Vue 1分钟实现右键菜单,懒人的福音!
- Vue 如何快速实现头像裁剪?方法比你想象的简单
- 前端持久化之浏览器存储技术(localStorage、sessionStorage 、session、cookies)