Backbone.js内存管理,DOM节点数上升

Cor*_*son 15 javascript mustache google-chrome-devtools backbone.js zepto

情况:我正在开发一个相当复杂的单页Backbone应用程序,可能会连续运行8-12个小时.因此,需要确保应用程序不会泄漏并在X小时后崩溃或显着减速.

应用程序:该应用程序基于Backbone(mv*),Zepto(类似于jquery),Curl(amd loader)和Mustache(模板)构建.

问题:我刚刚征服了事件监听器.垃圾收集器似乎在清理这些人员方面做得很好,但DOM Node Count不会停止攀爬.

问题:

  • 是否有正确的方法来处理DOM节点以便它们被正确地垃圾收集,或者这个DOM节点计数是否会永远不会减少?
  • 有没有人知道任何这些框架处理DOM节点?可能是小胡子?
  • DOM节点计数甚至是可靠的数字吗?

我真的只是想在我的冒险中找到一个先机,以阻止这些DOM节点上升.任何帮助或指导将不胜感激(并相应地投票).

我假设一旦事件监听器被妥善处理,DOM节点计数就会自行管理,但事实并非如此.

测试


管理不善的DOM节点数

  • 第一次测试:6.8分钟,110,000个DOM节点

编辑:没有时间轴录制,我重新使用相同的脚本随机混搭链接并在7分钟左右拍摄截图.GC发布后我得到了这些结果.

管理不善的DOM节点数

  • 第二次测试:7.1分钟,141,000个DOM节点(没有时间线记录)

编辑:修复后:

DOM节点计数受控制 升级Backbone并使用listenTo和stopListening到处都是

  • 7分钟:6,926个DOM节点(见下面的标记答案).
  • 20分钟:6,000个DOM节点,20个事件监听器,20 MB内存.
  • 25分钟:11,600个DOM节点,44个监听器,内存21.7 MB.
  • 28分钟:9,000个DOM节点,22个事件监听器,内存21.7 MB.
  • 30分钟:13700个DOM节点,123个事件监听器,内存21.7.
  • 31分钟:7,040个DOM节点,30个监听器,内存21.7.

Yur*_*sky 9

我假设一旦事件监听器被妥善处理,DOM节点计数就会自行管理,但事实并非如此.

如果我说得对,你试图通过从中移除侦听器来处置节点,是这样吗?

请注意,将事件侦听器添加到DOM节点不会阻止节点被垃圾回收,依赖性是相反的方向:当节点处于活动状态时,将不会收集侦听器函数.

  • 是否有正确的方法来处理DOM节点以便它们被正确地垃圾收集,或者这个DOM节点计数是否会永远不会减少?

要确保可以对DOM节点进行垃圾回收

  1. 从文档树中删除节点.
  2. 清除从javascript到节点从同一子树中的所有节点的所有引用,从javascript到子树中的一个节点将引用整个子树.

因此,仅从节点中删除侦听器以使其可收集是不够的.此外,如果要收集节点,则无需从节点中删除侦听器.

当GC收集并销毁某些节点时,DOM节点计数应该减少.该数字表示已创建但未销毁的DOM节点的当前数量,因此除非存在内存泄漏,否则它不应无限增长.

  • DOM节点计数甚至是可靠的数字吗?

是.它应该是一个可靠的数字,因为它在创建新DOM节点时递增,在销毁时递减.因此,信任它的实现非常简单.


Cor*_*son 6

这是固定的! - UPGRADE BACKBONE.(继续阅读)

我们从Backbone 0.9.2升级到Backbone 0.9.10,并在每个视图/模型/集合上实现了listenTo和stopListening.结果是OMGFANTASTIC.

运行相同的压力测试7分钟后,结果如下: 在此输入图像描述

结果:7.0分钟,6,926个DOM节点(没有时间线记录)和事件监听器计数看起来像BLUE BLADES OF GRASS.我感到震惊.与之前的测试相比,内存使用率也非常低.

18分钟后:事件监听器计数相同,从未超过154,DOM节点计数在整个时间内保持在25,000以下!显然有些东西正在滑落(一些非骨干组件仍然在使用,最有可能),但改进令人震惊.

结论:在此版本的Backbone之前,我们在Backbone本身内清理监听器方面做得不是很好.DOM的监听器处理得很好,但不能处理模型/视图/集合之间.所涉及的许多回调都与Backbone Views捆绑在一起,我想这可以防止垃圾收集器释放DOM节点.Backbone中的大量分散事件监听器/回调(不仅仅是绑定到DOM)创建了许多无法进行垃圾回收的分散DOM节点.

如果这不是升级Backbone的足够理由,我不知道是什么; o