性能测试正常但JS代码卡顿,车辆移动不流畅求助
嘿,我看到你的问题了——draw()函数本身耗时不足2ms,每10ms执行一次,但车辆移动还是不流畅,这种情况我之前也碰到过好几次,大概率是动画同步逻辑或者移动计算方式出了问题,给你几个具体的排查和解决方向:
换掉setInterval,改用requestAnimationFrame
你当前用固定10ms间隔调用draw(),但浏览器的屏幕刷新频率通常是60Hz(约16.6ms刷新一帧),setInterval的触发时机完全不跟浏览器渲染节奏同步,这会导致两种问题:要么某次draw()执行后浏览器还没到刷新时机,绘制内容被缓存到下一帧;要么同一帧里连续执行两次draw(),造成跳帧。而requestAnimationFrame会自动对齐浏览器的刷新周期,保证每一次绘制都能刚好赶上渲染时机,从根源上减少跳帧感。基于时间差计算移动距离,而非固定步长
如果你现在是每次draw()都让车辆移动固定像素数,那一旦draw()的执行间隔不稳定(比如主线程被其他任务占用,间隔超过10ms),车辆的移动速度就会忽快忽慢,视觉上自然不流畅。正确的做法是引入时间差(deltaTime)来计算移动距离:记录上一帧的时间戳,用当前帧时间减去上一帧时间得到deltaTime,再用速度乘以时间差来计算移动量。示例代码如下:let lastTimestamp = performance.now(); function draw(currentTimestamp) { // 计算两次绘制的时间差(毫秒) const deltaTime = currentTimestamp - lastTimestamp; lastTimestamp = currentTimestamp; // 假设车辆移动速度是 150 像素/秒 const moveDistance = 150 * (deltaTime / 1000); car.position.x += moveDistance; // 更新车辆位置 // 你的其他绘制逻辑... // 继续下一帧 requestAnimationFrame(draw); } // 启动动画 requestAnimationFrame(draw);检查完整帧的渲染耗时(不止是draw()函数)
你用performance.now()统计的只是draw()函数本身的执行时间,但浏览器渲染一帧还包含**布局(Layout)和绘制(Paint)**两个关键阶段,这些耗时是在draw()执行完成后由浏览器后台处理的,并没有被计入draw()的耗时里。打开Firefox的Performance工具,录制一段车辆移动的过程,查看每一帧的总耗时:如果布局或绘制阶段耗时过长(比如超过16.6ms),那就是这里拖慢了动画。举个例子:如果你的车辆是DOM元素,频繁修改left/top会触发重排,换成transform: translate()可以利用GPU加速,大幅减少重排开销。排查主线程的阻塞任务
看看页面是否存在其他占用主线程的任务,比如长时间的AJAX请求、后台定时器、或者复杂的计算逻辑,这些任务会抢占draw()的执行时机,导致帧间隔不稳定,进而造成视觉卡顿。用Firefox的Performance工具查看主线程的任务队列,有没有执行时间超过50ms的长任务,如果有,建议把这些任务拆分成多个小任务,或者放到Web Worker中执行,避免阻塞主线程的动画渲染。
如果能提供完整的代码片段,我还可以帮你更精准地定位问题,但先试试上面这几个方向,应该能解决大部分移动不流畅的情况。
内容的提问来源于stack exchange,提问作者sad

