在 javascript 运行时中查看 animation 耗时,最直接的方法是使用 requestanimationframe 的回调时间戳与 performance.now() 进行对比。通过记录动画开始和结束时的精确时间,可以计算出实际渲染帧的耗时。这种方法能准确反映浏览器合成线程的实际表现,而非仅依赖 js 主线程的执行速度。

如何获取单帧动画的精确执行时间
要获取单帧动画的精确执行时间,需要在 requestAnimationFrame 回调中调用 performance.now()。该函数返回自页面加载以来的高精度毫秒数,精度可达微秒级。将当前帧的时间戳与上一帧或初始时间戳相减,即可得到两帧之间的间隔,即动画一帧的耗时。

let lastTime = performance.now();
function animate(currentTime) {
const delta = currentTime - lastTime;
console.log(`Frame took: ${delta.toFixed(2)}ms`);
lastTime = currentTime;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
上述代码会持续输出每一帧的耗时。如果动画流畅,这个值通常接近 16.67ms(对应 60fps)。若出现明显波动,说明存在掉帧或主线程阻塞。
如何分析动画过程中的性能瓶颈
分析动画性能瓶颈时,除了帧间隔,还需关注 performance.getEntriesByType('paint') 和 PerformanceObserver。这些 API 能捕获重绘、布局等关键步骤的时间点。结合 requestAnimationFrame 的时间戳,可以定位是哪一步骤导致了延迟。

const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`${entry.name}: ${entry.startTime}ms, duration: ${entry.duration}ms`);
}
});
observer.observe({ entryTypes: ['paint', 'largest-contentful-paint'] });
通过观察 Paint 和 Layout 的持续时间,可以判断是否因样式计算或 DOM 操作过多导致动画卡顿。将这些数据与帧间隔对比,就能明确瓶颈所在。
当动画帧率低于 60fps 时如何排查具体原因
当动画帧率低于 60fps 时,应检查 requestAnimationFrame 回调中的同步代码是否过重。如果回调内包含大量 DOM 查询或复杂计算,会阻塞主线程,导致下一帧无法及时调度。此时可使用 setTimeout 或 Web Worker 将计算卸载到后台线程。
例如,若发现某帧耗时超过 33ms(30fps),可尝试将非视觉相关的计算移至 Web Worker,并在主线程仅更新必要的样式属性。这样能确保 requestAnimationFrame 回调快速返回,维持高帧率。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











