鼠标跟随动画怎么实现才不卡顿?

炳光 阅读 25

我在做一个鼠标跟随的小圆点效果,但一动起来就特别卡,尤其在高分辨率屏幕上。我试过用 mousemove 监听然后直接改元素的 left/top,但性能很差。

是不是应该用 transform?或者加个 requestAnimationFrame?下面是我现在的代码:

document.addEventListener('mousemove', (e) => {
  const follower = document.querySelector('.follower');
  follower.style.left = e.pageX + 'px';
  follower.style.top = e.pageY + 'px';
});

有没有更流畅的写法?感觉现在掉帧很严重。

我来解答 赞 6 收藏
二维码
手机扫码查看
1 条解答
UE丶玉霞
你这代码卡顿主要因为每次 mousemove 都在触发重排,改 left/top 浏览器得重新计算布局,高分辨率屏幕上开销更大。

几个优化点:

第一,用 transform 代替 left/top,translate3d 能触发 GPU 加速,不走主线程的布局计算。

第二,mousemove 触发频率极高,每秒能跑上百次,直接操作 DOM 肯定炸。用 requestAnimationFrame 做个节流,把 DOM 更新放到下一帧渲染前统一处理。

给你个流畅的写法:

const follower = document.querySelector('.follower');
let mouseX = 0;
let mouseY = 0;
let followerX = 0;
let followerY = 0;

document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
});

function animate() {
// 这里加个缓动效果,数值越小跟随越慢越丝滑
followerX += (mouseX - followerX) * 0.15;
followerY += (mouseY - followerY) * 0.15;

follower.style.transform = translate3d(${followerX}px, ${followerY}px, 0);
requestAnimationFrame(animate);
}

animate();


CSS 配合一下:

.follower {
position: fixed;
top: 0;
left: 0;
width: 20px;
height: 20px;
border-radius: 50%;
background: #333;
pointer-events: none;
will-change: transform;
}


注意安全事项:will-change 属性别滥用,只给真正需要的元素加,否则反而浪费显存。另外 pointer-events: none 很重要,不然跟随元素会挡住下面的点击事件,用户会疯。

如果你的页面后续有动态卸载这个组件的需求,记得把 animate 函数的循环停掉,否则会内存泄漏。可以加个标志位控制,或者用 cancelAnimationFrame。

还有一点,clientX/clientY 比 pageX/pageY 更稳定,后者在有滚动条的场景下计算会出问题。
点赞 2
2026-02-28 21:03