我认为我在jQuery UI可拖动库中发现了内存泄漏,虽然问题可能是由Meteor引起的,我不确定。
当我的应用程序第一次被一组用户全天使用时,我首先注意到了这一点。我在应用程序中打开了应用程序,当天结束时它很慢,无法使用。我检查了内存使用情况,发现它几乎占用了整整GB的内存。
为了重新创建这个问题,我编写了一个PhantomJS脚本,该脚本登录到应用程序并进行一系列更新,同时记录Chrome开发工具中的内存使用情况。所以我去寻找导致问题的代码,发现它是我在模板的渲染事件中放置元素的可拖动/可放置事件。
以下是我的幻像脚本以draggable运行时内存使用的示例:
这是我没有可拖动的内存使用情况:
注意:我试过可拖动的&可以与ZERO配置选项一起放置,也可以单独放置,并且没有发现泄漏的明显变化。
从第一张图中可以看出,脚本停止运行后(大约1.4分钟)内存使用量没有被释放,并且内存使用量增加了很多(14.3 MB到169 MB)。这大概运行了300-500次更新(这可能不是那么不切实际,特别是在一天中有很多用户的情况下)。
我认为此处的关键是Chrome在时间线标签中为您提供的节点数。脚本运行后,根据DOM节点计数有100 000多个DOM节点,第二个节点大约有1000个。
我创建了一个完全独立的项目来确保这个问题是真实的。我把这个放在github上供任何人玩。我的phantomJS脚本位于根目录中。
https://github.com/davidworkman9/jQueryDraggableMemLeakWithMeteor
我不确定从这里开始,无论是Meteor还是jQuery UI,或者如果没有任何一个软件包的解决方案,问题是可以解决的。
答案 0 :(得分:0)
对于遇到此问题的任何人,我设计了一个临时修复程序(这适用于每个模板重新渲染)。
(function () {
var oldRender = Spark.renderToRange;
Spark.renderToRange = function (range, htmlFunc) {
var oldFunc = htmlFunc;
htmlFunc = function () {
// put in clean up code here Example:
if(range._start === $('#myTemplate')[0]) {
$('#myTemplate').find('.ui-draggable').draggable('destroy');
}
// end clean up code
return oldFunc.apply(this, arguments);
};
return oldRender.apply(this, arguments);
};
})();
Google网上论坛论坛的一位Meteor Core开发人员告诉我(link)他们正在重写模板包,这将解决这个问题。