记录一次Vite打包优化
记录一次Vite打包优化
前几天刚刚把毕设做完,使用的是Vue3 + Vite
进行开发。在部署上线之后我发现页面加载速度很慢,因此看了几种常用的优化方式,对页面进行了一些优化。这里进行一下记录,主要记录为什么要做这个优化以及具体的做法。
0. 准备工作:安装打包分析插件
首先安装一个rollup
插件rollup-plugin-visualizer
,其目的是为了清晰的展示打包时长以及各个chunk
的大小。插件很好用,强烈建议安装。
安装:
$ pnpm add rollup-plugin-visualizer -D
引入插件:
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [
...,
visualizer() // 这个插件放在 plugins 的最后
],
})
之后每次打包后,该插件都会在根目录生成stats.html
,在浏览器打开后就可以看到各个chunk
的大小信息:
1. 代码分割(页面懒加载)
这部分优化的目的是把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,从而达到懒加载的效果。
这部分只需要改动vue-router
的配置文件,把静态导入都改为动态导入即可:
// 将
// import UserDetails from './views/UserDetails.vue'
// 替换成
const UserDetails = () => import('./views/UserDetails.vue')
const router = createRouter({
// ...
routes: [{ path: '/users/:id', component: UserDetails }],
})
打包工具会自动将动态导入作为打包的代码分割点。
2. gzip 压缩
之所以要使用gzip
压缩是为了减少服务端向客户端所传输文件的大小,从而节省传输文件的时间。值得注意的是,由于浏览器解压文件也需要时间,其成本可能大于传输中节约的时间,因此对于过小的文件不应该使用gzip
压缩。
gzip
的压缩分为静态压缩和动态压缩,顾名思义,动态压缩就是nginx
服务器上的文件都是原始文件,当浏览器请求时nginx
会对请求的文件进行压缩;而静态压缩则是指服务器上的文件是提前压缩好的文件,当浏览器请求时,nginx
只需直接返回对应文件即可。
为了减轻服务器的压力,我使用的是静态压缩。要开启gzip
压缩,分为两步:
-
配置
vite
,使其在打包时生成对应文件的压缩文件。-
添加插件
vite-plugin-compression
$ pnpm add vite-plugin-compression -D
-
在
vite.config.js
中使用插件import viteCompression from 'vite-plugin-compression' export default defineConfig({ plugins: [ ..., viteCompression({ threshold: 102400 // 对大于 100kb 的文件进行压缩 }), ... ], })
-
-
配置
nginx
,使其开启gzip
模式。只需要配置一下nginx.conf
即可,这里不写了。
3. 使用 CDN
之所以要使用CDN
是因为它可以让用户从距离它们最近的节点访问内容,从而减少网络延迟和带宽,提高网页访问速度;此外还可以减轻服务器的压力,起到负载均衡的作用。
由于项目中使用了three.js
和echarts
作为生产依赖,而他们的大小都较大,因此可以使用CDN
来提高加载速度。
要使用CDN
,首先要在index.html
中引入CDN
(CDN
引入方式都是在对应依赖的官网找到的):
<!-- echarts -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.1/dist/echarts.min.js"></script>
<!-- importmap 不是所有浏览器都支持,因此需要一个 polyfill -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>
<!-- three.js -->
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@v0.147.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@v0.147.0/examples/jsm/"
}
}
</script>
之后配置vite.config.js
,这里需要使用插件rollup-plugin-external-globals
:
$ pnpm add rollup-plugin-external-globals -D
然后修改配置文件:
- 使用
external: ['echarts', 'three']
告诉vite
在打包的时候不需要打包echarts
和three
两个库 - 使用
globals
告诉vite
在import * as echarts from echarts
和import * as THREE from three
时,echarts
和THREE
都来自外部CDN
,否则项目会在解析这两个依赖时报错,说依赖不存在
import externalGlobals from 'rollup-plugin-external-globals'
const globals = externalGlobals({
echarts: 'echarts',
THREE: 'three',
})
export default defineConfig({
build: {
rollupOptions: {
external: ['echarts', 'three'],
plugins: [globals],
}
}
})
4. Element-Plus 按需导入
虽然Element-Plus
也是体积很大的外部依赖,但是我没有选择使用CDN
,而是选择了使用官方文档提供的按需导入方式。这种方式的好处在于可以只导入使用了的组件的资源(在打包的时候自动注册使用了的组件,其他未使用的都会被tree-shake
掉)。相比之下,全局导入和CDN
的文件体积都较大,没有这个来的好。
使用上是通过antfu
的unplugin-vue-components进行按需导入的,使用方法详见文末参考文献。
5. 开启 HTTP/2
这部分和题目其实有些脱节,毕竟不属于打包优化的范畴了,但是考虑到也是常用的优化手段,因此也放了进来。
之所以使用HTTP/2
是因为它相比于HTTP/1.1
有了重大的优化(二进制分帧、多路复用、压缩标头),传输速度更快,延迟更低。
要开启HTTP/2
只需要配置nginx.conf
即可,使用方法详见文末参考文献。值得注意的是如果源站不支持HTTP/2
,则在实际传输时协议会降级到HTTP/1.1
。
参考文献
转载自:https://juejin.cn/post/7244820297278455865