浏览器中一帧内的事件顺序示意(约 16.6ms,约 60fps)。
总览
一帧时间预算约 16.6ms。从左到右大致为:输入事件 → JavaScript → Begin Frame → requestAnimationFrame → Layout → Paint → 空闲。
主流程图(一帧内,左 → 右)
下列阶段在同一段帧预算内顺序推进(与教学用示意图一致;不同浏览器实现细节会略有差异)。
flowchart LR
A["① 输入事件\n阻塞 touch·wheel\n非阻塞 click·keypress"] --> B["② JavaScript\n定时器 + 任务"]
B --> C["③ Begin Frame\nresize · scroll · media query"]
C --> D["④ requestAnimationFrame"]
D --> E["⑤ Layout"]
E --> F["⑥ Paint"]
F --> G["⑦ Idle\nidle 回调"]
Layout / Paint 子步骤(接续 ④ rAF 之后)
flowchart LR
L1["Recalculate style"] --> L2["Update layout"]
L2 --> P1["Compositing update"]
P1 --> P2["Paint invalidation"]
P2 --> P3["Record"]
P3 --> IDLE["⑦ Idle · idle 回调"]
说明:若在支持 Mermaid 的编辑器中预览(如 VS Code + 插件、GitHub),上图会渲染为流程图;纯文本阅读时也可对照下文分节标题。
1. 输入事件
- 阻塞型输入:如
touch、wheel。 - 非阻塞型输入:如
click、keypress。
2. JavaScript 执行
- 定时器:
setTimeout、setInterval等回调。 - 通用 JavaScript:任务队列中的同步/异步脚本执行。
3. Begin Frame(开始帧)
每帧可能触发的典型事件:
window的resizescrollmedia query变化
4. requestAnimationFrame
- 执行通过
requestAnimationFrame注册的 Frame callbacks。 - 适合与下一屏绘制对齐的更新与测量。
5. Layout(布局)
- Recalculate style:计算样式,确定规则如何应用到元素。
- Update layout:更新布局,计算几何信息(位置与尺寸)。
6. Paint(绘制)
- Compositing update:合成层更新。
- Paint invalidation:标记需要重绘的区域。
- Record:记录绘制指令。
7. Idle(空闲)
若前述步骤在 16.6ms 内完成,剩余时间为空闲期,可执行 idle 回调(例如 requestIdleCallback),如 idle callback1、idle callback2。
小结
输入 →(定时器 + JS) Begin Frame 事件(resize / scroll / media)→ rAF → 样式与布局 → 合成 / 失效 / 记录绘制 → 空闲期执行 idle 回调。