主题
05 · 性能优化:渲染路径、长列表、虚拟滚动
目标:说清重排 / 重绘 / 合成直觉;长列表会选分页或虚拟滚动;能用 Performance 抓一项前后对比。
1. 背景与目标
空谈「用了 memo」不算优化。本篇验收:同一场景有可对比数字或录屏。
2. 核心概念
2.1 渲染路径(极简)
text
JS 改 DOM/样式 → Style → Layout(重排) → Paint(重绘) → Composite(合成)1
| 动作 | 大致成本 |
|---|---|
改 transform / opacity | 常可走合成,相对便宜 |
| 改宽高、字体、插入大量 DOM | 易触发重排,贵 |
| 一帧里反复读布局再写样式 | 强制同步布局,更贵 |
2.2 长列表策略
| 策略 | 适用 | 代价 |
|---|---|---|
| 分页 / 无限滚动加载 | 多数业务列表 | 实现简单 |
| 虚拟滚动 | 上千行同屏滚动 | 复杂度、滚动复位、动态行高 |
| 减渲染成本 | 单元格过重 | 拆组件、少嵌套、图片懒加载 |
默认:先分页;真卡到滚不动再虚拟化。
3. 最小实践
3.1 用 Performance 定位
- Chrome DevTools → Performance → 录制滚动卡顿段
- 看 Long Task、Scripting、Rendering
- 数一下:是否一次挂了几千个 DOM 节点
3.2 对照实验(示意)
坏:一次 v-for 渲染 5000 行完整卡片。
好:只渲染可视区 ± buffer(虚拟列表库或自写 windowing)。
js
// 窗口思想(伪代码)
const start = Math.floor(scrollTop / rowHeight)
const visible = items.slice(start, start + viewportCount + buffer)1
2
3
2
3
3.3 记一笔「改前改后」
| 指标 | 改前 | 改后 |
|---|---|---|
| 节点数 / 交互耗时 / FPS | ? | ? |
没有数字就谈不上验收。
4. 踩坑与取舍
- 过早虚拟化:百级列表用虚拟滚动,收益小、坑多(焦点、锚点、动态高度)。
- 无效 memo:依赖每次新引用,
memo/computed形同虚设。 - 只看 Lighthouse 总分:实验室分数 ≠ 用户机型与弱网。
- 图片与字体:列表卡顿常是解码与布局抖动,不只是「框架慢」。
5. 验收清单
- [ ] 能口述重排 / 重绘 / 合成差别(面试 1 分钟版)
- [ ] 对一个列表做过 Performance 录制
- [ ] 选过分页或虚拟滚动之一,并说明理由
- [ ] 留下改前改后一项指标
