性能指标
- LCP/Largest Contentful Paint/最大内容绘制:可视区内容最大的可见元素出现在屏幕上的时间
- 一旦用户与网页互动(通过点按、滚动或按键操作),该指标就会停止记录
- FID/First Input Delay/首次输入延迟:用户第一次在页面上交互的时候(点击链接、点击按钮或者自定义基于 js 的事件),到浏览器实际开始处理这个事件的时间。
- 主线程被其他逻辑阻塞时,无法响应用户交互事件(比如执行一个较大的 js 文件)
- CLS/Cumulative Layout Shift/累计布局偏移:测量整个页面生命周期内发生的所有意外布局偏移中最大一连串的布局偏移分数
比如在页面未加载完全时,想要点击页面某个未知,结果页面的广告刚刚加载完动态注入了页面,导致点击的地方被偏移,点到了广告,造成用户交互行为不期望的结果。 可能会导致偏移的因素:
- 无尺寸的图片、iframe、广告、嵌入内容
- 动态注入的内容
- 网页字体
- FP/First Paint/首次绘制:页面绘制出第一个像素的时间
- 通常用来衡量白屏时间
- FCP/First Contentful Paint/首次内容绘制:绘制出一个内容的时间。文本、图片(包括背景图片)、
<svg>
元素或非白色<canvas>
元素 - FMP/First Meaningful Paint/首次有意义绘制:无准确标准,通常不考虑
- DCL/DOMContentLoaded/DOM 解析完成:HTML 被完全加载解析时,触发该事件
- 不等待样式表、图片等内容的加载
- 如果 HTML 中包含脚本,会阻塞该过程,在脚本执行完后继续解析 HTML
defer
脚本不会阻塞 HTML 解析,且在DOMContentLoaded
事件之前执行完毕async
脚本加载后立即执行,可能会阻塞 HTML 解析,对DOMContentLoaded
事件的影响不确定,可能会在之前或之后执行
- L/Onload/onload 事件触发:页面上所有的 DOM、样式表、脚本、图片都已加载完成,即整个页面完全加载完成
- FSP/First Screen Paint/首屏渲染时间:页面从开始加载到首屏内容全部绘制完成的时间
- 无标准规则,根据业务确定
工程优化
网络配置、资源配置、构建配置等
使用 HTTP/2 - 现在已经普及
- 服务端推送
- 文本协议改为二进制协议
- 头部压缩
- 多路复用:一次 TCP 连接并行传输连接
- 但是依然要注意控制请求数量
- CDN 按请求次数计费的情况
- 多一次请求,后端就要多一次鉴权
- 在特殊环境下(网络不稳定),一次请求比多次请求更稳定
- 但是依然要注意控制请求数量
静态资源使用 CDN
CDN 服务会根据用户的 IP,找到合适的缓存节点给用户向下发资源
图片资源优化
- 配合目标设备屏幕大小设置图片大小
- 对于支持 WebP 格式的浏览器使用 WebP 格式图片
- 小图标可以使用 iconfont、base64、svg 替代
预加载
将所需资源提前加载到本地,需要时直接从缓存取,能够减少用户等待时间
包体积优化
- 使用包分析工具分析是否有能够拆分的、重复打包的、无用的包
- 一些公共依赖使用 splitChunk 进行分块提取
- 第三方库按需引入(组件库、echarts 等),尽量避免全局导入
- vue、vue-router 这类全局引入并且基本不会改动的公共库使用 externals 排除,通过 cdn 的方式引入
- SPA 项目路由拆分懒加载,保证首页加载速度
- tree shaking,删除未使用的代码
- 代码压缩、删除 log、删除注释等
- 对 html、js、css 资源进行 gzip 压缩
构建速度优化
- 使用速度分析工具分析各个 loader、plugin 的消耗时间,进行针对性的优化
- 配置 loader 查找范围等
- 多进程打包:thread-loader
- webpack5 的持久化缓存,缓存上次的构建产物,可以在下次构建时直接读取使用
- 多入口应用开发时按需构建指定页面
- 预构建一些不需要更改的库,例如:vue、dayjs
代码优化
图片懒加载
当用户需要访问这张图片的时候再去加载它,能够提高首屏速度降低服务器压力。
一般的做法是将图片链接设置在一个自定义属性上, src
属性设置为空字符串,当图片进入可视区域时,从自定义属性上去到链接赋值给 src
属性。
防抖节流
- 防抖:事件在一定时间段内重复触发时,只执行最后一次(停止事件触发后 n 毫秒后执行,如果在 n 毫秒内又触发了事件,则会重新计时)
- 搜索框的建议项、或是输入后自动搜索
- 自动保存
- 表单输入检测
- 节流:无论触发多少次事件,在指定的时间间隔内只会执行一次(执行效果类似匀速运动的打点计时器)
- 拖拽事件,避免高频次触发
- 交互动画,避免短时间内多次触发导致性能问题