编写高性能JavaScript(译)(6)

提示:在理想情况下,若想确保你的分析并未受到已安装的应用程序或扩展的任何影响,可以使用--user-data-dir <empty_directory>标志来启动Chrome。在大多数情况下,这种方法优化测试应该是足够的,但也需要你更多的时间。这是V8标志能有所帮助的。

避免内存泄漏——3快照技术

在谷歌内部,Chrome开发者工具被Gmail等团队大量使用,用来帮助发现和排除内存泄漏。

devtools

devtools

Chrome开发者工具中的内存统计

内存统计出我们团队所关心的私有内存使用、JavaScript堆的大小、DOM节点数量、存储清理、事件监听计数器和垃圾收集器正要回收的东西。推荐阅读Loreena Lee的。该技术的要点是,在你的应用程序中记录一些行为,强制垃圾回收,检查DOM节点的数量有没有恢复到预期的基线,然后分析三个堆的快照来确定是否有内存泄漏。

单页面应用的内存管理

单页面应用程序(例如AngularJS,Backbone,Ember)的内存管理是非常重要的,它们几乎永远不会刷新页面。这意味着内存泄漏可能相当明显。移动终端上的单页面应用充满了陷阱,因为设备的内存有限,并在长期运行Email客户端或社交网络等应用程序。能力愈大责任愈重。

有很多办法解决这个问题。在Backbone中,确保使用dispose()来处理旧视图和引用(目前在中可用)。这个函数是最近加上的,移除添加到视图“event”对象中的处理函数,以及通过传给view的第三个参数(回调上下文)的model或collection的事件监听器。dispose()也会被视图的remove()调用,处理当元素被移除时的主要清理工作。Ember 等其他的库当检测到元素被移除时,会清理监听器以避免内存泄漏。

Derick Bailey的一些明智的建议:

与其了解事件与引用是如何工作的,不如遵循的标准规则来管理JavaScript中的内存。如果你想加载数据到的一个存满用户对象的Backbone集合中,你要清空这个集合使它不再占用内存,那必须这个集合的所有引用以及集合内对象的引用。一旦清楚了所用的引用,资源就会被回收。这就是标准的JavaScript垃圾回收规则。

在文章中,Derick涵盖了许多使用Backbone.js时的常见,以及如何解决这些问题。

Felix Geisendörfer的在Node中调试内存泄漏的教程也值得一读,尤其是当它形成了更广泛SPA堆栈的一部分。

减少回流(REFLOWS)

当浏览器重新渲染文档中的元素时需要 重新计算它们的位置和几何形状,我们称之为。回流会阻塞用户在浏览器中的操作,因此理解提升回流时间是非常有帮助的。

reflow

reflow

回流时间图表

你应该批量地触发回流或重绘,但是要节制地使用这些方法。尽量不处理DOM也很重要。可以使用,一个轻量级的文档对象。你可以把它作为一种方法来提取文档树的一部分,或创建一个新的文档“片段”。与其不断地添加DOM节点,不如使用文档片段后只执行一次DOM插入操作,以避免过多的回流。

例如,我们写一个函数给一个元素添加20个div。如果只是简单地每次append一个div到元素中,这会触发20次回流。

function addDivs(element) { var div; for (var i = 0; i < 20; i ++) { div = document.createElement('div'); div.innerHTML = 'Heya!'; element.appendChild(div); } }

要解决这个问题,可以使用DocumentFragment来代替,我们可以每次添加一个新的div到里面。完成后将DocumentFragment添加到DOM中只会触发一次回流。

function addDivs(element) { var div; // Creates a new empty DocumentFragment. var fragment = document.createDocumentFragment(); for (var i = 0; i < 20; i ++) { div = document.createElement('a'); div.innerHTML = 'Heya!'; fragment.appendChild(div); } element.appendChild(fragment); }

可以参阅 , 和 Finding Memory Leaks

JS内存泄漏探测器

为了帮助发现JavaScript内存泄漏,谷歌的开发人员((Marja Hölttä和Jochen Eisinger)开发了一种工具,它与Chrome开发人员工具结合使用,检索堆的快照并检测出是什么对象导致了内存泄漏。

leak

leak

一个JavaScript内存泄漏检测工具

有完整的文章介绍了,建议你自己到看看。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgpywd.html