性能优化整体思路
优化的本质是减少关键路径上的工作量。按用户体感分三个阶段:加载(白屏到可交互)、渲染(页面流畅度)、运行时(交互响应)。
一、加载阶段:让首屏更快
1. 资源体积瘦身
1 | # 生产构建开启压缩 |
图片是体积大户:能 WebP/AVIF 就用,能 CDN 就上 CDN,能懒加载就懒加载。
2. 缓存策略
1 | # 带 hash 的静态资源:长缓存 |
3. 懒加载:图片和路由
1 | <!-- 图片懒加载:进入视口才加载 --> |
1 | // 路由懒加载(Vue) |
4. 预加载关键资源
1 | <!-- 首屏关键字体/图片提前加载 --> |
5. 减少请求数
- 小图标合并成 SVG sprite 或直接用 iconfont/icon 组件;
- 小的装饰图片 base64 内联(阈值 8KB 左右);
- API 合并:首屏多个接口能合并就合并,减少往返。
二、渲染阶段:让页面不卡
1. 减少重排(Layout)
重排代价极高,常见的”罪魁祸首”:
1 | // 反模式:循环里反复读写布局属性,强制同步重排 |
经验法则:动画用 transform + opacity,别用 top/left/width。
2. 虚拟列表:长列表必备
渲染 1 万个 DOM 节点页面必卡。虚拟列表只渲染可视区域的节点:
1 | // 简单思路(社区库 vue-virtual-scroller / react-window 同理) |
业务里出现”一次性渲染几百上千条数据”的列表,直接上虚拟列表。
3. 减少不必要的渲染
1 | // React:memo 防止无关 props 变化触发渲染 |
4. 防抖节流
1 | // 防抖:停止触发后才执行(搜索输入) |
搜索用防抖,滚动用节流,别搞反。
三、运行时优化
1. 事件委托
1 | // 反模式:1000 个 li 每个绑一个监听 |
2. 大数据计算放 Worker
1 | // 主线程不卡 |
图片压缩、加密、复杂排序这类 CPU 密集任务丢给 Worker。
3. 内存注意
- 组件卸载时清掉定时器和事件监听(React useEffect 清理函数、Vue onUnmounted);
- 大对象用后置空引用;
- 用
WeakMap/WeakSet缓存数据,避免强引用阻止 GC。
四、测量:先量化再优化
1 | # 性能预算检查 |
Chrome DevTools 三个关键面板:
- Performance:录制交互,看长任务(Long Task)和主线程占用;
- Network:看阻塞时间和资源体积;
- Lighthouse:Core Web Vitals 分数(LCP、INP、CLS)。
优化顺序建议:LCP(首屏最大内容)→ 图片体积 → 缓存 → 懒加载 → 长列表虚拟化 → 动画 transform 化。先测后改,改完复测。
常见坑
- 只优化不测量:凭感觉改,可能白忙;先记录优化前后指标;
- 过度懒加载:首屏关键图片/内容被懒加载反而拖慢 LCP;
- 缓存配错:html 也长缓存,导致发布后用户一直看旧版本;
- 虚拟列表滚动抖动:行高不定时高度估算不准确,建议固定行高或预测量。
总结
性能优化是系统工程:加载阶段抓体积和缓存,渲染阶段抓重排和渲染数量,运行时抓事件和内存。记住”先测量、再优化、后复测”的铁律,对照 Core Web Vitals 逐个击破。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 JCAlways!
评论
