vite学习笔记之Vite项目优化

436 阅读4分钟

开发阶段,我们更多的是关注开发体验,在生产环境,我们更多的是关注运行时的性能。 开发阶段的构建性能问题,Vite 内部已经做了相当多的优化,实现了项目秒级启动与毫秒级热更新。这里我们介绍下线上环境的项目加载性能优化。

关于性能优化:

  1. 网络优化。包括 HTTP2DNS 预解析等手段。
  2. 资源优化。包括构建产物分析资源压缩产物拆包按需加载等优化方式。

网络优化

  1. HTTP2

    HTTP1.1存在队头阻塞的问题,同一个TCP只能处理一个http请求,也就是说当前请求没有处理完其他请求都是处于阻塞状态中。浏览器对同一个域名下的并发请求数量也是有限制,如Google最多只能同时处理6个请求并发,超出6个只能排队或者等待发送请求。

    因此,在 HTTP 1.1 协议中,队头阻塞请求排队问题很容易成为网络层的性能瓶颈。而HTTP2就是为了解决这些问题而出现的。

  • 多路复用:将数据分为多个二进制帧,多个请求和响应的数据帧在同一个TCP通道中传输,解决了队头阻塞的问题,在HTTP2中浏览器不在限制同一域名下并发请求数量限制。

  • Server push:服务端推送能力。

在Vite中我们可以通过vite-plugin-mkcert在本地serve中开启HTTP2

pnpm i vite-plugin-mkcert -D

然后在vite.config.js中配置使用

// vite.config.js 
import { defineConfig } from "vite"; 
import vue from '@vitejs/plugin-vue'
import mkcert from "vite-plugin-mkcert"; 

export default defineConfig({ 
    plugins: [vue(), mkcert()], 
    server: { // https 选项需要开启 
        https: true 
    }
});
  1. DNS预解析

浏览在向跨域的服务器发送请求时,首先会进行DNS解析,将服务器域名解析为对应的IP地址。通过dns-prefetch将DNS解析提前,降低DNS解析延迟的时间。

<!-- href 为需要预解析的域名 --> 
<link rel="dns-prefetch" href="https://fonts.com/">

一般情况下 dns-prefetch会与preconnect 搭配使用,前者用来解析 DNS,而后者用来会建立与服务器的连接,建立 TCP 通道及进行 TLS 握手,进一步降低请求延迟。使用方式如下所示:

<link rel="preconnect" href="https://fonts.com/" crossorigin> 
<link rel="dns-prefetch" href="https://fonts.com/">

资源优化

  1. 产物分析报告

rollup-plugin-visualizer来进行产物分析。使用方式如下:

//vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { visualizer } from "rollup-plugin-visualizer";

export default defineConfig({
  plugins: [vue(),
    visualizer({
      // 打包完成后自动打开浏览器,显示产物体积报告
      open: true,
    })
  ]
})

接下来我们来看下Element-plus 完整引入和自动引入打包后的对比

完整引入后的打包分析 image.png

自动引入后的打包分析

image.png

  1. 资源压缩
  • javascript文件

在Vite生产环境构建中,会自动对js产物进行压缩

// vite.config.js 
export default { 
    build: { 
        // 类型: boolean | 'esbuild' | 'terser' 
        // 默认为 `esbuild` 
        minify: 'esbuild', 
        // 产物目标环境 
        target: 'modules', 
        // 如果 minify 为 terser,可以通过下面的参数配置具体行为 
        // https://terser.org/docs/api-reference#minify-options 
        terserOptions: {} 
    } 
}
  • CSS代码
// vite.config.js 
export default { 
    build: { 
        // 设置 CSS 的目标环境 
        cssTarget: '' 
    } 
}
  • 图片压缩

图片资源是一般是产物体积的大头,如果能有效地压缩图片体积,那么对项目体积来说会得到不小的优化。而在 Vite 中我们一般使用 vite-plugin-imagemin来进行图片压缩

  1. 产物拆包

如果不对产物拆包会有以下问题

  • 首屏加载的代码体积过大,即使是当前页面不需要的代码也会进行加载
  • 线上缓存复用率极低,改动一行代码即可导致整个 bundle 产物缓存失效

Vite 中内置如下的代码拆包能力

  • CSS 代码分割,即实现一个 chunk 对应一个 css 文件
  • 默认有一套拆包策略,将应用的代码和第三方库的代码分别打包成两份产物,并对于动态 import 的模块单独打包成一个 chunk
  1. 按需加载

在一个完整的 Web 应用中,对于某些模块当前页面可能并不需要,如果浏览器在加载当前页面的同时也需要加载这些不必要的模块,那么可能会带来严重的性能问题。一个比较好的方式是对路由组件进行动态引入,