likes
comments
collection
share

记录一次Vite打包优化

作者站长头像
站长
· 阅读数 43

记录一次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的大小信息:

记录一次Vite打包优化

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压缩,分为两步:

  1. 配置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 的文件进行压缩
          }),
          ...
        ],
      })
      
  2. 配置nginx,使其开启gzip模式。只需要配置一下nginx.conf即可,这里不写了。

3. 使用 CDN

之所以要使用CDN是因为它可以让用户从距离它们最近的节点访问内容,从而减少网络延迟和带宽,提高网页访问速度;此外还可以减轻服务器的压力,起到负载均衡的作用。

由于项目中使用了three.jsecharts作为生产依赖,而他们的大小都较大,因此可以使用CDN来提高加载速度。

要使用CDN,首先要在index.html中引入CDNCDN引入方式都是在对应依赖的官网找到的):

<!-- 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在打包的时候不需要打包echartsthree两个库
  • 使用globals告诉viteimport * as echarts from echartsimport * as THREE from three时,echartsTHREE都来自外部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的文件体积都较大,没有这个来的好。

使用上是通过antfuunplugin-vue-components进行按需导入的,使用方法详见文末参考文献。

5. 开启 HTTP/2

这部分和题目其实有些脱节,毕竟不属于打包优化的范畴了,但是考虑到也是常用的优化手段,因此也放了进来。

之所以使用HTTP/2是因为它相比于HTTP/1.1有了重大的优化(二进制分帧、多路复用、压缩标头),传输速度更快,延迟更低。

要开启HTTP/2只需要配置nginx.conf即可,使用方法详见文末参考文献。值得注意的是如果源站不支持HTTP/2,则在实际传输时协议会降级到HTTP/1.1

参考文献

官方文档:Element-Plus 按需导入

怎样把网站升级到http/2

Nginx 启用 HTTP/2 不生效的原因排查

我是如何把 Vite 的打包时间从 110s 优化到 25s 的

转载自:https://juejin.cn/post/7244820297278455865
评论
请登录