如果用户说 web 应用感觉很反应慢或者卡顿,该如何排查?

如果用户觉得 web 应用反应卡顿, 主要从哪几个方面来排查?

  • 加载慢
    • 资源下载慢
    • 首屏并发请求资源过多
    • 首屏接口慢
    • 首屏对应的 JS 执行慢
    • 首屏渲染慢
    • 首屏加载静态资源过大
    • .......
  • 执行过程慢
    • 接口慢
    • long tasks 太多, 阻塞 JS 执行
    • 内存泄漏
    • 重绘重排 过多
    • 关键节点没有加 节流防抖
    • .......

主要排查手段有哪些

  • 通过建立性能监控指标: 通过真实用户数据反馈, 来判断用户是否卡顿, 包含网络监控、运行时性能监控

  • Chrome devtools: NetWork 主要排查网络问题
    image

  • Chrome devtools: Performance 主要细查性能运行时性能,包含了 long tasks、render 次数、重排重绘、执行时间线、阻塞场景
    image

  • Chrome devtools: Performance monitor 主要监控用户运行时性能,看看是否有内存泄露
    image

  • React Developer Tools: 可以用于追踪 react 应用性能、渲染次数、重排重绘
    image

  • Lighthouse: 全面分析网页性能的一个工具、支持浏览器插件
    image

  • webpack-bundle-analyzer: 进行产物依赖分析、包大小分析

  • 抓包: 通过抓包的方式, 看看线上请求分析、请求模拟、网络劫持之后仅仅看 JS 执行时间

  • E2E测试: 通过 E2E 进行性能预检, 每次上线前进行一系列系统操作, 看看时间耗时和线上耗时波动

主要解决办法和思路

首屏加载慢的方向

  • 资源加载方向

    • 使用 tree shaking 减少包体积
    • 代码压缩和混淆
    • 对于高版本浏览器, 直接使用 ES6 语法,低版本浏览器再使用 ES5(es6 语法代码量会比编译成 es5 代码量小很多, 且执行速度也快)
    • 使用 split chunks 进行大包拆分、小包复用
    • 使用 gzip
    • 使用 图片压缩
    • 使用 雪碧图
    • 图标使用 iconfont 加载
    • 懒加载, 仅加载首屏必要资源
    • 使用 tailwindcss 等技术, 复用 css
    • 使用 微前端 技术,首屏仅加载当前子应用页面,可以做到只加载整站很少的一部分代码
    • 首屏非必要依赖尽量延后到 FMP 或者 TTI 之后再加载
    • 组件微前端化
  • 渲染方向

    • 尽量减少重排重绘
    • 减少重复渲染(useMemo、useCallback、memo 等)
    • 减少 setState 次数(多次 setState 可以合并为一次)
    • 尽量减少 dom 节点深度
  • 网络方向

    • 使用流式服务端渲染, 可以查看文档:https://juejin.cn/post/6953819275941380109
    • 使用服务端渲染, 减少首屏请求
    • 使用 SSG 静态站点生成
    • 首屏必要数据, 不作客户端请求, 用后端模板注入
    • 使用 BFF 进行请求聚合
    • 使用 CDN 进行网络请求分发
    • DNS Prefetch
    • 资源预加载(在闲暇时间加载后续页面所需要的资源和接口,例如:link rel preload)
    • 启用 HTTP2 多路复用
    • 在业务逻辑上, 首屏必要接口提前(例如在 html 加载的那一瞬间,利用一个非常小的 js 文件将首屏需要的请求发送出去, 然后缓存下来, 到业务使用的时候直接就使用即可)
    • 使用缓存技术缓存资源与请求:强缓存、协商缓存、离线缓存、Service Worker 缓存、后端业务缓存

运行时卡顿方向

  • 查看是否存在有有 long tasks, 有计划的拆解 long tasks
  • 解决项目中复杂度问题: https://www.jianshu.com/p/ffbb25380904
  • 排查项目是否有内存泄露
  • 排查特定业务流程是否有慢接口
  • 高复杂计算逻辑放在 service worker 处理

参考文档