0

我有一个在backboneJS中构建的测验应用程序,我有三个视图。 QuizView显示整体进度和后退/下一个按钮。包含一组问题和每个问题的QuestionView的PageView。删除骨干视图但DOM节点数不断增加?

当用户转到测验的下一页时,我通过调用一个调用Backbone的remove()函数的页面本身和所有问题来删除当前的PageView。 (所有听众都附带listenTo)

这是我的期望,在我这样做后,DOM节点不应该再反映在内存时间轴上。我附加了Chrome开发工具中DOM节点数的视图,您可以看到它随着您进入新页面而增加。

我也拍了堆快照,当我查看分离的DOM项目时,它们都有一个项目(页面的div容器),在保留树中有一个项目。我假设这就是为什么他们没有被收集。

任何人都可以提供洞察,为什么DOM节点数不断增加?

而且这是我破坏功能浏览量:

destroy: function(){ 
    console.log("PageView :: destroy " + this) 
    _.each(this.childViews, function(view){ 
     view.remove(); 
    }); 

    this.remove(); 
} 

Timeline View Heap Snapshot

回答

0

只要你拥有他们将没有资格进行垃圾回收的对象之间的任何引用。这些观点是“僵尸观点”。如何处理这类案件在这个职位是完全解释说:

Zombies! RUN! (Managing Page Transitions In Backbone Apps)


通过

view.remove()删除从DOM视图,并调用的stopListening到 删除视图听过的任何绑定事件。

您基本上删除了events: {}和该视图的DOM。然而,事件的trigger和模型事件监听像

this.model.on('reset', this.render, this) 

依然健在,而且持有参考您的视图,使其无法进行垃圾回收。

+0

这是有道理的,但是在我的“上”或“触发”任何事件的情况下我不会用,所以我觉得默认的删除功能应该是足够的。 – smurfarita 2013-05-12 20:42:58

+0

如果你有任何listenTo在你的视图/集合/模型中,最好选择'this.model.off(null,null,this)'或'this.collection.off(null,null,this)' – Muhaimin 2014-03-03 14:35:57

0

我知道这是一个旧帖子,但我碰到了同样的问题。 在chrome dev工具中记录时,垃圾收集器不能运行。您必须通过单击GC按钮手动运行它。

Dev Tools GC Button

我建this fiddle创建节点,然后将它们全部删除时创建10。认为节点计数应该在从dom中移除时重置。它没。然后我注意到顶部的GC按钮...

猜你可以将演示注入到SO中。不需要小提琴。这很酷...

var test = document.getElementById("test"); 
 
var stuff = document.getElementById("stuff"); 
 

 
test.addEventListener("click", testFn); 
 

 
var count = 0; 
 

 
function testFn(){ 
 
    
 
    console.log('create '+count); 
 
    
 
    // create a new div element 
 
    // and give it some content 
 
    var newDiv = document.createElement("div"); 
 
    var newContent = document.createTextNode("test "+count); 
 
    count++; 
 
    
 
    newDiv.appendChild(newContent); //add the text node to the newly created div. 
 
    
 
    stuff.appendChild(newDiv); 
 
    
 
    if(count == 10){ 
 
     
 
     while (stuff.firstChild) { 
 
      stuff.removeChild(stuff.firstChild); 
 
     } \t \t \t 
 
     
 
     count = 0; 
 
     
 
    } \t 
 
    
 
};
<div id="test">page should start with 14 nodes. click me.</div> 
 
<div id="stuff">&nbsp;</div>