用 useState 做动画卡顿,该怎么优化?
我在 React 里用 useState 控制一个元素的位置做简单动画,但一动就掉帧,特别卡。明明只是改个 left 值,为啥这么慢?
试过用 requestAnimationFrame 包裹 setState,但没效果。是不是不该用状态驱动动画?
const [position, setPosition] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setPosition(prev => prev + 1);
}, 16);
return () => clearInterval(id);
}, []);
return <div style={{ position: 'absolute', left: position }}>移动块</div>;
你试了 requestAnimationFrame 包裹 setState,但其实没解决根本问题:你还是在每一帧里调用了 setState,React 依然要走一遍生命周期,只是节奏变准了而已,没变快。
真正该做的是绕过 React 的渲染机制,直接操作 DOM,或者用纯 CSS 动画。比如你这个场景,用
requestAnimationFrame+ref操作 DOM 属性是最轻量的方案:或者更狠一点——直接用 CSS transition:
加个
transition: none是为了防止 React 更新时意外触发浏览器的重排/重绘优化逻辑,但其实更推荐直接用 transform 动画:注意用
transform而不是left,因为 transform 是 GPU 硬件加速的,不会触发重排,性能好很多。总结一句:状态驱动高频动画是反模式,React 不是动画引擎,别拿它当定时器用。动效类逻辑,要么直接操作 DOM,要么用 CSS,要么上专业库比如 Framer Motion、GSAP,别硬刚 setState。