在 javascript 运行时中查看 fps 变化,最可靠的方法是利用 requestanimationframe 的回调时间戳计算帧间隔。通过记录每帧开始时的 performance.now() 时间戳,并与上一帧的时间戳相减,即可得到当前帧的耗时(frame time)。将 1000 毫秒除以该耗时,即可得出瞬时 fps;若需观察趋势,可维护一个滑动窗口或累加器来计算平均 fps。这种方法直接挂钩渲染循环,能准确反映主线程的实际表现。

如何实时计算并输出当前帧的 FPS 数值
要获取实时的 FPS 数值,需要在每一帧执行时更新全局时间变量并计算差值。核心逻辑是:在 requestAnimationFrame 回调中,获取当前时间 currentTime,减去上一帧时间 lastTime 得到 delta。如果 delta 大于 0,则 FPS 为 1000 / delta。为了避免首帧数据异常,通常初始化 lastTime 为当前时间或 0,并在第一次计算后更新它。此方法简单直接,适用于需要逐帧监控的场景。

let lastTime = performance.now();
let frameCount = 0;
let fps = 0;
function updateFPS() {
const currentTime = performance.now();
const deltaTime = currentTime - lastTime;
// 避免首帧 delta 为 0 导致除零错误
if (deltaTime > 0) {
fps = Math.round(1000 / deltaTime);
console.log('Current FPS:', fps);
}
lastTime = currentTime;
requestAnimationFrame(updateFPS);
}
requestAnimationFrame(updateFPS);运行上述代码后,控制台会持续打印类似 "Current FPS: 60" 或 "Current FPS: 30" 的数值。这些数值对应每一帧的渲染速度。注意,由于 requestAnimationFrame 通常在屏幕刷新率(如 60Hz)下触发,FPS 往往呈现阶梯状变化(如 60, 59, 30),这是正常现象。开发者应关注 FPS 是否稳定在目标值附近,而非单帧的微小波动。
立即学习“Java免费学习笔记(深入)”;
你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型
如何通过平滑算法消除 FPS 数据的抖动
瞬时 FPS 数据因帧间隔的离散性而剧烈跳动,不利于性能分析。为了获得更稳定的指标,应采用移动平均法(Moving Average)对 FPS 进行平滑处理。具体做法是维护一个固定大小的数组或累加器,存储最近 N 帧的 FPS 值(或帧间隔时间)。每次新帧到来时,移除最旧的数据点,加入最新数据点,然后计算平均值。例如,使用长度为 30 的窗口,可以平滑掉单帧卡顿带来的尖峰,反映出整体性能趋势。这种处理方式更符合人类对“流畅度”的感知。

const windowSize = 30; // 滑动窗口大小
const fpsHistory = [];
let lastTime = performance.now();
function smoothFPS() {
const currentTime = performance.now();
const deltaTime = currentTime - lastTime;
lastTime = currentTime;
if (deltaTime > 0) {
const currentFps = 1000 / deltaTime;
fpsHistory.push(currentFps);
// 保持窗口大小
if (fpsHistory.length > windowSize) {
fpsHistory.shift();
}
// 计算平均 FPS
const avgFps = fpsHistory.reduce((a, b) => a + b, 0) / fpsHistory.length;
console.log('Smoothed FPS:', Math.round(avgFps));
}
requestAnimationFrame(smoothFPS);
}
requestAnimationFrame(smoothFPS);使用平滑算法后,输出的 FPS 值变化更为平缓。例如,当发生短暂卡顿导致瞬时 FPS 降至 20 时,平滑后的 FPS 可能仅从 60 降至 58,随后逐渐恢复。这有助于开发者识别长期的性能退化,而非被单帧噪声干扰。在实际应用中,可根据需求调整 windowSize,较大的窗口提供更稳定的平均值,但响应延迟更高;较小的窗口更敏感,但波动更大。
当主线程阻塞时 FPS 数据会呈现什么特征
当 JavaScript 主线程执行长时间同步任务(如复杂计算、大型 DOM 操作)时,requestAnimationFrame 回调会被推迟执行,导致帧间隔 deltaTime 显著增大。此时,计算的瞬时 FPS 会骤降,甚至出现连续多帧丢失的情况。例如,若主线程阻塞 100ms,则下一帧的 deltaTime 约为 100ms + 渲染耗时,FPS 可能跌至 10 以下。平滑后的 FPS 也会随之下降,但幅度取决于阻塞时长和滑动窗口大小。这种特征是诊断主线程过载的关键指标。


















