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

如何彻底销毁EaselJS画布?解决enableMouseOver定时器残留问题

解决EaselJS enableMouseOver() 定时器残留导致的内存/CPU占用问题

我之前也踩过EaselJS这个定时器残留的坑!你分析的完全正确——enableMouseOver() 会创建一个原生的 setInterval 定时器来检测鼠标悬停状态,但这个定时器不会被removeAllEventListeners()或者stage的常规销毁代码自动清除,所以每个创建过的画布都会留下一个持续运行的定时器,时间久了必然导致内存和CPU占用飙升。

下面是具体的解决步骤,亲测有效:

1. 保存定时器ID

在你调用 enableMouseOver() 的时候,一定要保存它返回的定时器ID——很多人会忽略这个返回值,但这是清除定时器的关键:

// 类组件初始化时(比如componentDidMount)
this.mouseOverTimer = this.stage.enableMouseOver();

// 如果是函数组件,可以用useRef来保存:
// const mouseOverTimerRef = useRef(null);
// mouseOverTimerRef.current = stage.enableMouseOver();

2. 组件销毁时清除定时器

在React组件销毁的生命周期里(类组件用componentWillUnmount,函数组件用useEffect的清理函数),除了你现有的销毁代码,加上定时器清除逻辑:

// 类组件示例
componentWillUnmount() {
  // 先清除mouseOver定时器
  if (this.mouseOverTimer) {
    clearInterval(this.mouseOverTimer);
    this.mouseOverTimer = null;
  }
  
  // 执行你原来的销毁代码
  createjs.Touch.disable(this.stage);
  this.stage.removeAllChildren();
  this.stage.removeAllEventListeners();
  this.stage.enableDOMEvents(false);
  
  // 最后清空stage引用,帮助垃圾回收
  this.stage = null;
}

// 函数组件示例(useEffect清理)
useEffect(() => {
  const stage = new createjs.Stage(canvasRef.current);
  const mouseOverTimer = stage.enableMouseOver();
  
  return () => {
    // 清理定时器
    clearInterval(mouseOverTimer);
    // 销毁stage相关资源
    createjs.Touch.disable(stage);
    stage.removeAllChildren();
    stage.removeAllEventListeners();
    stage.enableDOMEvents(false);
  };
}, []);

为什么之前的代码没效果?

removeAllEventListeners() 只能清除EaselJS内部注册的事件监听器,而 enableMouseOver() 创建的是原生JavaScript的setInterval定时器,它不属于EaselJS的事件系统范畴,所以必须手动调用clearInterval来清除。

内容的提问来源于stack exchange,提问作者Rehan Haider

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:24:12