【问题标题】:Backbone memory leak Detached DOM主干内存泄漏 分离的 DOM
【发布时间】:2014-07-06 22:38:15
【问题描述】:

我正在使用 Chrome 开发工具中的分析器查看分离的 DOM 树,在测试下面的代码时,我猜我发现了内存泄漏。 工作流程如下:

  1. 加载页面
  2. 拍摄堆快照 => 没有任何分离的 dom 树
  3. 点击过滤器事件,过滤集合并再次呈现表格
  4. 获取堆快照并与前一个比较 => 有一个分离的树

调试代码后发现问题出在下面一行

this.listenTo(this.model, "clearView", this.remove); //Line with problem    

如果我删除了这条线,则没有分离的 dom 树,否则我有分离的 dom 树。我想解开一些东西吗?任何帮助将不胜感激。

谢谢。

var Post = { Views: {} };

Post.Model = Backbone.Model.extend({

    initialize: function() {
    },

    destroyView: function() {
    }
});

Post.Collection = Backbone.Collection.extend({
    model: Post.Model,
    url: '/posts'
});

Post.Views.ModelView = Backbone.View.extend({
    tagName: 'tr',
    template:  APP.Templates.PostModel,

    initialize: function() {
        this.listenTo(this.model, "clearView", this.remove); //Line with problem
    },

    render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    },

    remove: function() {
        console.log("remove");
    }
});

Post.Views.CollectionView = Backbone.View.extend({
    template: APP.Templates.PostCollection,

    events : {
        "click .filter":"filter",
        "click .delete":"clear"
    },

    initialize: function() {
        this.toRenderModels = this.collection.models;
    },

    filter: function() {
        this.toRenderModels = null;
        this.toRenderModels = this.collection.where({title: 'Post 1'});
        this.render();
    },

    clear: function() {
        this.toDeleteModel = this.collection.at(0);
    },

    render: function() {
        this.$el.empty();
        this.$el.html(this.template());
        _.each(this.toRenderModels, function(model) {
            this.$('table').append(new Post.Views.ModelView({model: model}).render().el);
            }, this);
        this.toRenderModels = null; 
        return this;
    }
});

【问题讨论】:

    标签: backbone.js memory


    【解决方案1】:

    您标记为“有问题的行”的行应该放在 View 的构造函数中。

    这里最重要的是调用 remove 方法来移除元素并停止监听事件。

    remove: function() {
      this.$el.remove();
      this.stopListening();
      return this;
    },
    

    这是一个默认实现,您不必复制粘贴它。

    相关问题:Memory Leak when deleting items from DOM using backbone

    【讨论】:

    • 同意您的回答,我将 el.empty() 替换为 removeViews() 实现,以便调用 stopListening 并解除事件绑定。
    猜你喜欢
    • 2013-05-29
    • 2014-02-09
    • 2020-05-28
    • 2014-02-04
    • 2017-11-16
    • 2011-09-18
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    相关资源
    最近更新 更多