# 指标性能优化

这篇文章更多的是一篇总结。站在以用户为中心的性能指标上,对网站做性能优化。

如何衡量 Web 体验?

  • 站点体验

    Web Vitals (opens new window) 定义了 LCP、FID、CLS 指标,成为了业界主流的标准。基于长期以来的体验指标优化积累,最新的核心体验指标主要专注于加载、交互、视觉稳定加载的速度决定用户是否可以尽早访问到视觉上的图像,可交互的速度则决定用户心理上是否可以尽快感觉页面上的元素可以操作,而视觉稳定性则负责衡量页面的视觉抖动对用户造成的负面影响。

    optimization1

  • 错误监控

    当页面达到数以亿计的访问量时,无论发布前单元测试、集成测试以及人工测试过了再多轮,都难以避免的会漏掉某些边缘操作路径的测试,甚至偶尔会出现难以复现的玄学故障。哪怕这些错误只有 0.1% 的出现率,在亿级访问量的站点也会导致用户遭遇百万次故障。

    我们对 JavaScript 错误、静态资源错误以及请求错误都提供了宏观的错误数、错误率、影响用户数、影响用户比例等指标,一目了然的关注到当前还存留的错误以及对用户的影响,以协助开发人员尽快修复问题。

    同时对于请求的监控,为了进一步保证用户在获取数据上的体验,我们还进一步的细化到了请求的成功率、慢查询相关的指标。

# 指标优化

# 优化 FP & FCP

尽快渲染,资源加载快、解析快、渲染快, FP 和 FCP 值越低,首屏渲染性能才会越优秀。通过这两个指标,就可以衡量页面何时开始渲染内容。官方推荐,FP 及 FCP 两指标在 2 秒内完成的话我们的页面就算体验优秀。

  • 消除阻塞首屏渲染的资源

  • 压缩 CSS & 分离 CSS & 移除未使用的 CSS

  • 预连接到所需的来源

  • 预加载关键请求

  • 避免 DOM 过大

  • 避免多个页面重定向

  • 避免巨大的网络负载

  • 使用高效的缓存策略缓存静态资产

  • 减少服务器响应时间 (TTFB)

  • 最小化关键请求深度

  • 确保文本在网页字体加载期间保持可见

  • 保持较低的请求数和较小的传输大小

# 优化 FMP & LCP & SI

缩短页面关键路径的渲染时间,涉及网络、资源、渲染等全链路优化。这三个指标,就可以衡量页面何时渲染出主要内容,也是 SEO 关键指标。官方推荐,在 2.5 秒内表示体验优秀。

主要受四个因素的影响:

  1. 缓慢的服务器响应速度 - 网络优化
  2. JS 和 CSS 渲染阻塞 - 资源体积、资源加载优化
  3. 资源加载时间 - 网络优化、资源加载优化
  4. 客户端渲染 - 关键渲染路径优化

# 网络优化

针对缓慢的服务器响应速度

  • 使用 http/2 协议,同时做好域名收敛
  • 使用 CDN 部署和加载静态资源
  • DNS 预解析
  • preconnect 提前建立网络连接
  • 提升 HTTPS 性能

# 资源体积优化

针对 JS 和 CSS 渲染阻塞、资源加载

  • 压缩 HTML/JS/CSS
  • 分离 CSS 样式,成单独 bundle
  • 按需引入
  • 利用 Tree-Shaking
  • 图片内联或使用 CDN
  • 优化 SourceMap
  • 路由懒加载
  • Code Split 代码分割
  • CDN 动态加载 polyfill(动态垫片)
  • 依赖外置并 CDN 加载

# 资源加载优化

针对资源加载时间

  • 延迟加载非关键 CSS

  • 内联关键 CSS

  • 图片优化。图片 CDN 加载、图片懒加载、优化和压缩图片、使用高性能图片

  • 静态资源 CDN 加载

  • preload & prefetch 预加载重要资源

  • 路由懒加载、延迟加载未使用的 JS 文件。

  • 利用浏览器缓存

  • 资源加载优化,减少网络请求次数

    • 压缩静态资源文件
    • 合理进行 js、css 分包,并利用 HTTP/2
    • 减少外部脚本数量
    • 懒加载或者按需加载
    • 行内图片(Base64编码)、图片懒加载、使用 webp 等高性能图片格式
    • 使用字体图标,iconfont 代替图片图标
    • 浏览器缓存(强缓存与协商缓存)
  • 服务端处理优化

    • 接口优化,Redis缓存、数据库存储和查询优化、系统内的各种中间件优化、Gzip压缩等

性能优化之接口优化 (opens new window)

# 渲染优化

  • 减少复杂的样式计算和嵌套

    • 减少重排重绘
    • 减少长任务执行时间,例如利用 web worker、时间片分割
    • 利用防抖节流优化用户输入事件
    • 使用服务端渲染 SSR
    • 预渲染
    • 骨架屏

# 优化 TTI & TBT

何时可交互。TTI 值越小,代表用户可以更早地操作页面,用户体验就更好。所以需要页面尽快的渲染、尽早的请求、请求尽快结束、尽量避免长任务等提高页面可交互性。

  • 参考如何优化 FCP
  • 预加载关键请求
  • 最小化关键请求深度
  • 减少 JS 执行时间
  • 最小化主线程工作
  • 保持较低的请求数和传输大小
  • 加载采用 PRPL 模式

# 优化 FID & MPFID

交互时是否有延迟。这两个指标反应页面的可交互性,如何更快地响应用户交互是优化关键。针对 FID,我们一般建议通过 Code Splitting 等方式减少页面加载阶段 JS 的加载、解析和执行时间。而页面加载完成后的 Input Delay,通常是由于开发人员代码编写不当、引起 JS 执行时间过长而产生的。

  • 分割长任务、最小化主线程工作

  • 优化页面,尽快做好交互准备

    • 移除关键路径上非必要组件加载的脚本
    • 尽最大限度地减少需要在客户端进行后处理的数据量;
    • 按需加载第三方代码
    • 优先加载可以为用户提供最大价值的内容
  • 使用 Web Worker

  • 减少 JS 执行时间

  • 减小请求数量和请求文件大小

# 优化 CLS

CLS 衡量稳定性。代表了页面的稳定性指标。CLS 值一大的话会让用户觉得页面体验做的很差。CLS 推荐值为低于 0.1,越低说明页面跳来跳去的情况就越少,用户体验越好。

CLS较差的常见原因及优化手段:

  • 无尺寸的图像
    • 设置长宽、或者通过使用CSS 宽比容器预留所需的空间
  • 无尺寸的广告、嵌入和 iframe
    • 预留空间、避免在可视区域顶部放置广告、使用占位符或者预先计算足够的空间
  • 动态注入的内容
    • 预留空间,比如使用占位符或者骨架屏
  • 导致不可见文本闪烁 (FOIT)/无样式文本闪烁 (FOUT) 的网络字体
    • 预加载字体
  • 在更新 DOM 之前等待网络响应的操作
    • 倾向于选择 transform 动画,而不是触发布局偏移的属性动画(CSS 触发器和高性能动画)

# 如何分析

  • 首先我们可以利用 webpack 打包分析工具,资源包分析,开发体验优化。
  • 其次我们可以使用 networkPerormance等在本地进行测量,根据 Lighthouse 报告给出的一些建议进行优化
  • 发布之后,我们可以使用 PageSpeed Insights 去看下线上的性能情况
  • 接着,我们可以使用 Chrome User Experience Report API 去捞取线上过去28天的数据
  • 发现数据有异常,我们可以使用 DevTools 工具进行具体代码定位分析
  • 使用 Search Console’s Core Web Vitals report查看网站功能整体情况
  • 使用 Web Vitals 扩展方便的看页面核心指标情况
  • 使用前端监控平台查看线上运行性能指标,全链路优化。