【性能优化】vite+vue3

193 阅读4分钟

前言

  • 此文是本人在公司的小项目开发中结合网上资料整理所得
  • 文章主要以思路为主,细节可根据关键字另行检索

抛砖引玉:希望路过的巨佬能不吝赐教,指点一二优化手段

性能指标

作用
  • 性能优化的最终目的是体验优化
    • 体验优化太主观
    • 不同人、不同设备、不同网络情况下的体验是不同
  • 为了准确的监测性能情况,我们需要客观的、可量化的指标来说明性能状况
常用指标
  • 首次内容绘制 (First Contentful Paint,FCP)
    • 任意部分 DOM 完成渲染的耗时
  • 最大内容绘制 (Largest Contentful Paint,LCP)
    • 可视区域内尺寸最大的文字或图像渲染完成的耗时
    • 会受 http 请求时间影响
  • 首次输入延迟 (First Input Delay ,FID)
    • 用户首次交互(如点击按钮、链接等)后到浏览器开始响应之间的时间间隔
    • 受操作时机影响,完全加载后 FID 值就低
  • 交互到绘制延迟(Interaction to Next Paint,INP)
    • 在页面浏览过程中的所有交互(点击、键盘输入、触摸等)与浏览器渲染响应的整体延迟情况
  • 累积布局偏移 (Cumulative Layout Shift,CLS)
    • 监测的是所有非用户操作导致的布局偏移
    • ex. 资源加载、动态内容插入等原因,导致的页面元素位置的意外变化
  • 第一字节时间 (Time to First Byte,TTFB)
    • 测量 HTTP 请求发送后,到接收到第一字节数据响应的耗时,通常包括重定向、DNS查询、服务器响应延迟等耗时
数据采集
  • web-vitals
    • web-vitals 是谷歌的 Chrome 维护团队于 2020 年开源的工具库,它基于统一的浏览器 Performance API 获取标准化的用户体验指标,可用于开发环境的数据采集
  • Performance API
    • Performance API 是一组在浏览器平台测量和收集性能数据的接口,它允许开发者访问页面加载、资源获取、用户交互、JavaScript执行等性能相关的数据
数据可视化监控工具
  • Prometheus / Grafana
  • 将采集到的定制化数据上报
小结
  • 上述流程属于标准化性能监控流程
  • 小公司小项目还是体感为主,配合 lighthouse 进行优化即可

请求优化

  • 新版 http 协议
    • ex.http2 的多路复用、头部压缩
  • gzip 压缩
    • 加快网络传输
  • http 缓存
    • 静态资源采用强缓存,其余采用协商缓存
  • 资源优先级提示符
    • ex. 预取回 Prefetch
    • 用于提示浏览器在 CPU 和网络带宽空闲时下载指定 URL 的 JS,图片等各类资源,存储到浏览器本地缓存中
    • 预取回的资源不会进一步解析、运行该资源
  • cdn 配置

资源优化

  • 资源压缩
  • 资源懒加载
  • 图片九宫格
  • 图片格式:avif > webp > png/jpg
  • GIF 转视频
    • 视频格式有运动估计(Motion Estimation)、预测编码(Predictive Coding) 等专用的编码优化技术
    • 可以实现相邻帧优化,对于视频中相邻的几帧图像,只需要保存帧与帧之间的部分差异像素数据

代码优化

  • 移除全局变量
    • 方便树摇
  • 全量导入改为按需导入
    • lodash -> lodash-es
    • element plus
  • 虚拟滚动
  • 防抖 & 节流

产物优化

产物分析 rollup-plugin-visualizer

1、基础使用

pnpm add rollup-plugin-visualizer -D
// vite.config.ts
plugins: [
  visualizer({
    filename: 'stat.html', // 生成的可视化报告的文件名
    emitFile: true, // 是否将报告文件作为输出文件的一部分
    gzipSize: false, // 是否显示 gzip 压缩后的文件大小
    brotliSize: false, // 是否显示 Brotli 压缩后的文件大小
    open: true // 是否在生成报告后自动打开浏览器
  })
]

2、筛选

  • 筛选 bundle 和 文件
    • xxx-*.js:*/**/xxx.js
  • 筛选 bundle
    • */xxx-*.js:
  • 筛选文件
    • */**/xxx.js
优化思路
  • 入口用到的 npm 包与业务代码剥离,打包成 vendor chunk,降低http请求,提升缓存效率
  • 仅需对产物文件根据大小进行排序,对较大的包进行分析
  • 不常用的 npm 包可尝试动态导入
  • 较大的组件,例如对 wangEditor 封装过的组件可采用异步组件的方式进行导入
  • 坑点:做异步路由时,如使用到 import.meta.glob 需注意范围,涉及到的文件全都会被单独拆分