如何彻底销毁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
相关产品推荐
相关产品推荐

