JavaScript事件监听器内存泄漏

3
我正在使用React、Redux和Three.js开发一个WebGL应用程序。我的应用程序使用鼠标移动和点击作为输入。但是出现了一些问题,每当我点击或移动鼠标时,我的应用程序就会变得越来越慢。如下所示的性能分析表明,似乎存在某种内存泄漏,导致事件监听器使用的内存不断增长。

enter image description here

据我所知,截图中的黄线显示事件监听器不断增长的内存使用情况。
但是这条黄线到底代表什么?它是事件监听器使用的内存量吗?还是注册的监听器数量?或者是注册/未处理事件的数量?
有没有人在过去遇到过类似的问题,可能已经找到了解决方案?
我的应用程序/原型的完整代码可以在this repository中找到。不幸的是,我还没有能够隔离出问题的原因或在简单的代码片段中重现它。

似乎有很多监听器,实际上应该有多少个? - Teemu
蓝线表示内存占用情况。黄线表示页面中的侦听器数量。您是否不断向组件添加事件回调而不删除旧的回调函数? - Federico klez Culloca
1
鼠标点击和移动应该只有一个事件监听器。但是由于某种原因,每次点击/移动似乎都会添加一个额外的事件监听器。但这怎么可能呢?我的事件回调函数中没有类似.addEventListener()的东西。我只是将事件处理函数作为属性传递给我的组件,这是通常的React方式... - lsgng
我在一个类似的Webgl应用程序中遇到了同样的问题,但没有使用Three.js。 - kevzettler
2个回答

3

这可能只是一个开发人员的问题。如果使用 NODE_ENV=production 构建 React 项目,这个问题可能不会存在。

这似乎与 React 上的一个未解决问题有关: https://github.com/facebook/react/issues/12141


1
我已经快速查看了你的代码,我的猜测是你正在将=>函数传递给某些东西作为侦听器,然后稍后尝试将其删除(例如here)。你无法删除=>侦听器,因为每次调用渲染方法时都会创建一个新函数(因此在某个地方调用.removeEventListener(myArrowFunction)将尝试将该函数与已添加的函数进行匹配,但它们不相等。

无论如何,不要使用箭头函数作为侦听器。

编辑:嗯,是的,使用箭头函数,但声明为实例方法。或者存储为常量。而不是作为闭包。


1
但这不是React/Redux中处理事件的常规方式吗?(就像在此示例中一样)。据我所知,React处理事件/事件监听器注册与纯JS不同,因此在React中,onClick属性的工作方式与.addEventListener()不同。因此,更令人困惑的是为什么会有东西不断添加事件监听器。 - lsgng
React 可能会,但 ThreeJS 可能不会?这只是一个指针,帮助您深入了解问题 :-) - LoremIpsum
1
可能需要指向正确方向的指针 :-) 这可能真的是一个ThreeJS问题,因为一旦我从脚本中删除了ThreeJS渲染器,错误就不会发生。仍然很奇怪,特别是因为onClick处理程序并没有直接影响ThreeJS渲染器或其DOM元素... - lsgng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接