$.empty()与 Backbone 网的View.remove()的比较?

klr1opcd  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(175)

我知道当通过.remove()删除视图时,会在该视图上调用.stopListening(),以删除Backbone中与该视图关联的任何事件侦听器。

删除**视图.remove()

  • 从DOM移除检视,并呼叫stopListening来移除检视已监听的任何系结事件**。*

我有一些视图被附加到一个容器中,这些容器通过Backbone的events钩子只包含与dom操作相关的事件。

  1. var View = Backbone.View.extend({
  2. events : {
  3. 'input keyup' : 'searchDropdown'
  4. },
  5. searchDropdown: function () {
  6. $('dropdown').empty();
  7. //Appends views based on search
  8. }
  9. });

我的问题实际上是,当我在一个容器上调用$.empty()时,是否会泄漏任何内存(重要的或不重要的),而这个容器实际上删除了附加在其中的视图。如果是的话,有没有什么好的约定来访问和调用这些视图上的.remove()?

ryoqjall

ryoqjall1#

你不需要任何特殊的框架来完成这个任务,但是正确地执行删除是一个好主意,而不是依赖于足够智能的浏览器来完成这个任务。有时候在一个大的应用中,你会发现你特别需要覆盖remove方法来做一些特殊的清理--比如你在那个视图中使用了一个库,它有一个destroy方法。
一个现代的浏览器倾向于有一个GC,它对于大多数情况来说已经足够智能了,但是我仍然不喜欢依赖它。最近我在Backbone中做了一个项目,它没有子视图的概念,我通过将empty更改为remove,将泄漏节点减少了50(在Chrome 43中)。要让一个大型javascript应用程序不泄漏内存是非常困难的,我的建议是尽早监控它:If a DOM Element is removed, are its listeners also removed from memory?
注意那些会泄漏大量内存的东西--比如图像。我在一个项目中有一些代码,它做了这样的事情:

  1. var image = new Image();
  2. image.onLoad(.. reference `image` ..)
  3. image.src = ...

基本上是一个预加载器。而且因为我们没有显式地执行image = null,所以GC从来没有启动,因为回调引用了image变量。在一个图片较多的网站上,我们在每次页面转换时都会泄漏1- 2 mb,这会导致手机崩溃。在remove覆盖中将变量设置为null修复了这个问题。
在子视图上调用remove就像这样简单:

  1. remove: function() {
  2. this.removeSubviews();
  3. Backbone.View.prototype.remove.call(this);
  4. },
  5. removeSubviews: function() {
  6. if (!_.isEmpty(this.subViews)) {
  7. _.invoke(this.subViews, 'remove');
  8. this.subViews = [];
  9. }
  10. }

你只需要把你的子视图示例添加到一个数组中。例如,当你创建一个子视图时,你可以有一个像parentView: this这样的选项,并把它添加到父视图的数组中。我以前做过更复杂的子视图系统,但那会工作得很好。在初始化视图时,你可以做如下操作:

  1. var parentView = this.options.parentView;
  2. if (parentView) {
  3. (parentView.subViews = parentView.subViews || []).push(this);
  4. }
展开查看全部

相关问题