减少使用动画时的内存泄漏

减少使用动画时的内存泄漏

我最近在Snap.svg上做了很多工作,您可能已经看过一段时间有关SVG动画的文章

文章发表后,我花了一些时间检查我编写的代码,发现我造成了一些内存泄漏。 除非您监视网站的性能,否则通常不会意识到这种情况的发生。 为了向您展示如何查找内存泄漏,我将以我编写的Hill Valley动画为例。

Chrome浏览器“获取堆快照”

Chrome浏览器提供了一些很棒的工具,可以帮助您了解是否引起内存泄漏。 最简单的方法是使用“获取堆快照”。 在开发人员工具->个人资料中找到。 只需点击录制按钮。

首先要检查的是循环动画是否引起了内存泄漏。 为此,请按一系列间隔拍摄一个堆快照。 如下所示,内存大小正在莫名其妙地增长。

减少使用动画时的内存泄漏

现在我们有了这些快照。 我们可以使用比较工具来找出内存的主要增长位置。 为此,请选择最后一个快照,然后从摘要下拉列表中单击“比较”。

减少使用动画时的内存泄漏

现在,从类过滤器右侧的下拉列表中选择您的第一个快照。

减少使用动画时的内存泄漏

一旦浏览器已确定哪些工作需要由# 三角洲你的表进行排序。 现在,您将看到这些泄漏的来源,从顶部开始,然后逐步下降。 请注意,并非所有这些新事物都是内存泄漏,有时仅需要内存。

当我单击顶部的#Delta时,从堆栈跟踪中可以看到snap.svg的完成事件和mina的缓动算法导致了此情况。 代码的很多部分都可能导致这种情况,我现在将讨论。

减少使用动画时的内存泄漏

标记扫描算法

不幸的是,通过我们有时用JavaScript编写动画的方式,我们可以轻松地引入垃圾收集标记清除算法不会采用的模式。

简单地说,“标记并扫描”算法通过尝试确定对象是否不可访问来工作。 如果发现该对象不可访问,则会将垃圾回收应用于该对象。

这意味着,当您在循环中创建一个动画库单例,但从未将此分配设置为null时,垃圾回收将永远不会将自身应用于该对象。 作为一个对象仍然可以到达。

解决此问题的最简单方法是在动画结束后将变量重置为null。

动画积累

通过使用动画库,可以很容易地在内存中建立动画。 大多数库都有一个内置函数来尝试克服此问题,因为我们使用Snap.SVG构建了上一个教程,所以我将解释其版本。

Snap.SVG使用与jQuery相同的方法,即stop()函数。 它停止所有排队的动画,并继续新的动画。

计时器永远不会被清除

可能最常见的内存泄漏不仅发生在动画中,而且发生在网络上的一般UI界面中。 如果不删除对计时器的引用,则它只会在内存中徘徊,永远不会被垃圾回收删除。

对于大多数应用程序来说,这不是问题,因为在页面之间进行切换会删除页面时刷新页面。 但是,现在网络上到处都是一页纸的应用程序,您可以看到它如何Swift成为问题。

清除计时器的最佳方法是将其添加到数组中,然后在您认为最佳时,通常是新动画的开始或在js页面过渡之前。 清除所述计时器并重置阵列。

减少使用动画时的内存泄漏

关于迈克尔·风暴

Michael Tempest是RefME的首席前端开发人员。 他的爱好是骑自行车,滑雪,音乐和与设计/开发相关的所有事物。

michaeltempest.com mike_tempest 帖子

翻译自: https://davidwalsh.name/reducing-memory-leaks-working-animations