You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用多次点击随机移动按钮后页面卡顿如何优化

卡顿核心原因
  • 最根本的问题是useEffect没有指定依赖数组,每次组件重渲染都会新增一个mousemove事件监听器:你每点击一次按钮调用setchange就会触发组件重渲染,相当于每次点击都多绑定了一个鼠标移动监听函数,点击次数多了后,鼠标移动一次会触发成百上千个回调同时执行,直接导致页面卡顿。
  • 存在冗余的重复操作:你既用change状态控制绿色方块的left属性,又直接通过EN的ref修改style.left,而且样式里的left: "${change}px"写法错误(用了双引号而非反引号,模板字符串根本没生效),change状态完全没用,反而导致了不必要的组件重渲染。
  • 鼠标移动回调存在大量无效操作:同时修改元素的top/bottom/left/right四个定位属性,实际上只需要改left和top即可,再加高频触发的console.log也会额外占用性能。
  • 随机数生成逻辑位置错误:randomize变量定义在组件顶层,只有组件重渲染时才会生成新的随机值,多次点击按钮用的是同一个随机数,不符合随机移动的预期。
修复方案
  1. 给useEffect添加空依赖数组,保证全局只绑定一次mousemove监听器,同时添加清理函数在组件卸载时移除监听器,避免内存泄漏。
  2. 删掉没用的change状态和对应的setchange调用,避免不必要的组件重渲染,直接通过ref操作绿色方块位置即可。
  3. 优化mousemove回调逻辑,删掉无效的属性修改和console.log语句。
  4. 把随机数生成逻辑移到enem函数内部,保证每次点击都生成新的随机位置。
  5. 把固定不变的样式对象移到组件外部,避免每次渲染重复创建对象。
修正后完整代码
const { useRef, useEffect } = React

// 固定样式移到组件外,避免重复创建
const cursors = {
  pointerEvents: "none",
  borderRadius: "50%",
  width: "20PX",
  height: "20PX",
  backgroundColor: "red",
  position: "fixed",        
  transform:"translate3d(-10px,-10px,15px)",
};

const enemy = { 
  zIndex: "-1",
  borderRadius: "20%",
  width: "30PX",
  height: "30PX",
  backgroundColor: "green",
  position: "absolute",
  left: "1px",
};

const borders = {
  width: "1300px",
  height: "620px",
  background: "#ccc",
  border: "4px solid #333",
  position: "absolute",
  right: "500px"
}

const Main = props => {
  const textInput = useRef()
  const EN = useRef()
  const move = useRef()

  function enem() {
    // 随机数移到函数内部,每次点击生成新值
    const randomize = Math.floor(Math.random() * 1320)
    EN.current.style.left = randomize + "px"
  }

  useEffect(() => {
    // 提取监听函数,方便后续移除
    const handleMouseMove = (event) =>{
      textInput.current.style.top = event.clientY + 'px' 
      textInput.current.style.left = event.clientX + 'px' 
    }
    document.addEventListener("mousemove", handleMouseMove)
    // 添加清理函数,卸载时移除监听
    return () => document.removeEventListener("mousemove", handleMouseMove)
  }, []); // 空依赖数组,仅执行一次

  return (
    <div style={borders} >
      <div ref={textInput} style={cursors}></div>   
      <div style={enemy} ref={EN}></div>
      <div className={"pe"} ref={move}></div>
      <button onClick={enem}>Move randomly</button>
    </div>
  )
}

ReactDOM.render(<Main />, document.getElementById("root"));

内容的提问来源于stack exchange,提问作者eddie delgatto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:06:04