Performance API(如performance.now()、mark/measure、PerformanceObserver、requestIdleCallback)可高精度测量事件循环各阶段耗时,精准区分异步任务的排队等待时间与实际执行耗时。

JavaScript 的事件循环机制决定了异步任务(如 setTimeout、Promise.then、fetch 回调)何时被推入执行队列并真正运行。单纯用 console.time() 或 Date.now() 很难准确区分“排队等待时间”和“实际执行耗时”,而 Performance API(尤其是 performance.now() 和 performance.mark()/performance.measure())能提供高精度、不受系统时间调整影响的时间戳,非常适合结合事件循环阶段做细粒度测量。
用 performance.now() 捕获宏任务/微任务的精确起止点
performance.now() 返回以毫秒为单位的浮点数,精度可达微秒级(通常 5–10 μs),且单调递增,比 Date.now() 更可靠。关键在于在**正确时机打点**:
- 宏任务(如
setTimeout回调):在回调函数**第一行**记录开始时间,在**最后一行**记录结束时间 - 微任务(如
Promise.then):同理,但要注意它总在当前宏任务末尾、下一个宏任务开始前执行,所以其“等待时间”极短(通常 - 避免在事件监听器或 Promise 构造函数中打点——那测的是注册/创建耗时,不是执行耗时
分离“等待时间”与“执行耗时”的典型模式
要测一个异步任务从被调度到真正执行花了多久,需在调度时刻(如 setTimeout 调用时)和执行时刻(回调内)分别打点。例如:
等待耗时: ${(execStart - startMark).toFixed(2)}ms
注意:这里 startMark 是在主线程同步上下文中打的,代表任务被加入宏任务队列的理论时间点;实际入队时刻略晚于该调用(但差值可忽略)。若需更严谨,可用 performance.mark() 配合 performance.measure() 自动计算。
用 PerformanceObserver 监听长任务(Long Tasks)间接反映事件循环压力
浏览器会自动将执行 > 50ms 的连续 JS 任务标记为“长任务”。启用 PerformanceObserver 可捕获这些事件,从而判断当前事件循环是否拥堵:
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.duration > 50) {
console.warn(`长任务 detected: ${entry.duration.toFixed(1)}ms`, entry);
// 此时说明该宏任务阻塞了事件循环,后续异步任务等待时间可能增加
}
}
});
observer.observe({ entryTypes: ["longtask"] });
这不直接测某个任务,但能帮你定位“为什么某次 setTimeout 等待了 200ms 而不是预期的 100ms”——大概率是前一个长任务占用了主线程。
结合 requestIdleCallback 测量空闲时段可用性(适用于低优先级异步工作)
对于希望“不阻塞用户交互”的异步任务(如日志上报、非关键渲染),requestIdleCallback 是更合适的调度方式。它会在浏览器空闲时执行,并通过 deadline.timeRemaining() 告知剩余空闲时间:
requestIdleCallback((deadline) => {
const start = performance.now();
while (deadline.timeRemaining() > 0 && hasWork()) {
doOneUnitOfWork();
}
const end = performance.now();
console.log(`本次空闲执行耗时: ${(end - start).toFixed(2)}ms`);
}, { timeout: 2000 }); // 强制执行兜底
这里 timeRemaining() 本质是浏览器根据帧率(60fps ≈ 16.7ms/frame)和已用时间动态计算的,它隐含了事件循环当前负载状态——值越小,说明越忙。
本质上,Performance API 不改变事件循环行为,但它提供了观测它的“显微镜”。关键是把打点位置对应到事件循环的真实阶段:调度时刻、入队时刻(难直接获取)、出队执行时刻、执行完成时刻。只要时机抓准,就能清晰拆解出“等了多久”和“干了多久”。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










