1 Event Loop 执行顺序
- 同步代码直接执行。
- 遇到异步任务:
--setTimeout
、setInterval
、setImmediate
进入宏任务队列;
--Promise.then
、queueMicrotask
、MutationObserver
进入微任务队列。 - 每轮宏任务结束后,先清空微任务队列,再进入下一轮宏任务。
- 微任务全部执行完后,浏览器进行一次渲染(重排/重绘)。
示例:
js
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
console.log(4);
// 输出:1 4 3 2
2 浏览器渲染帧 16.67 ms 流程
- 样式计算:把 CSS 规则应用到 DOM 节点。
- 布局:计算每个节点的几何信息(位置、大小)。
- 绘制:把节点绘制成像素。
- 合成:把绘制结果合成到最终屏幕。
若总耗时 > 16.67 ms,页面掉帧。
优化:把动画放在 requestAnimationFrame
,避免强制布局抖动。
3 垃圾回收
- 新生代:对象存活时间短,使用 Scavenge 算法(复制存活对象)。
- 老生代:对象存活时间长,使用 Mark-Sweep + Mark-Compact 算法(标记-清除-整理)。
- 闭包泄漏 :函数返回后,其内部变量仍被外部引用,导致无法回收。
解决:引用置空或使用WeakMap
/WeakRef
。
示例泄漏:
js
function leak() {
const big = new Array(1e6);
return () => big.length; // big 被闭包引用
}
const f = leak(); // f 存在期间 big 无法回收
4 AST(抽象语法树)
- 源代码 → 词法分析 → Tokens → 语法分析 → AST → 字节码 → 机器码。
- 工具:
-- esbuild :Go 实现,速度快。
-- Babel :JavaScript 实现,转译新语法。
-- Terser:基于 AST 压缩代码。
示例 AST 节点:
js
// 源码:a + b
{
type: 'BinaryExpression',
operator: '+',
left: { type: 'Identifier', name: 'a' },
right: { type: 'Identifier', name: 'b' }
}
速查表
概念 | 关键点 |
---|---|
Event Loop | 宏任务→微任务→渲染 |
渲染帧 | 16.67 ms 内完成样式→布局→绘制→合成 |
垃圾回收 | 新生代复制、老生代标记整理;闭包引用置空 |
AST | 源码→树→字节码→机器码,esbuild/Babel/Terser 基于它 |
背下这张表,面试不再慌张。