Reducing Memory Leaks when Working with Animations

By  on  

I have been doing a lot of work with Snap.svg recently and you may have already seen an article a while back regarding SVG animations.

After the article had been published, I took some time out to review the code I had written and found that I had created some memory leaks. Unless you monitor your website's performance, you wouldn't normally realise this was occurring. To show you how to find memory leaks I will use my Hill Valley animation I wrote as an example.

Chromes 'Take Heap Snapshot'

Chrome has some great tools to understand whether you are introducing memory leaks. The easiest way to do so is to use 'Take Heap Snapshot.' Found in Developer Tools -> Profiles. Simply hit the record button.

The first thing to check is if a looping animation has caused the memory leak. To do this, take a heap snapshot at a series of intervals. As you can see below, the memory size is growing inexplicably.

Memory Leaks

Now we have these snapshots; we can use the comparison tool to figure out where the main growth in memory is. To do this, choose the last snapshot, and then click ‘Comparison' from the summary dropdown.

Memory Leaks

Now choose your first snapshot from the dropdown to the right of the class filter.

Memory Leaks

Once Chrome has worked out what it needs to sort your table by the #Delta. You will now see where those leaks are coming from, start at the top and work your way down. Please note, not all of these new things will be memory leaks, sometimes memory is just needed.

When I clicked on my top #Delta, I can see from the stack trace that the finish event of snap.svg and the easing algorithm of the mina caused this. Many parts of the code can cause this, which I will now discuss.

Memory Leaks

The Mark-and-Sweep algorithm

Unfortunately, with the way we sometimes write animations in JavaScript, we can easily introduce patterns that the Mark-and-Sweep algorithm for garbage collection won't pick up.

The Mark-and-Sweep algorithm in simple terms works by trying to work out if an object is unreachable. If it finds it that object is unreachable, it will apply garbage collection to that object.

That means that when you create a singleton of an animation library in a loop, but never set this assignment to null, garbage collection will never apply itself to that object. As an object is still reachable.

The easiest way to overcome this is simply reset the variable to null once the animation has ended.

Animations building up

With the use of animation libraries, it is very easy to have animations building up in memory. Most libraries have a built-in function to try and overcome this, as we built the previous tutorial with Snap.SVG, I will explain its version.

Snap.SVG uses the same method as jQuery that is the stop() function. It stops all queued animations and continues with the new animation.

Timers never being cleared

Probably the most common memory leak not only in animations, but in general UI interfaces around the web. If you do not remove the reference to a timer, it will simply hang around in memory never to be removed by garbage collection.

For most applications, this isn't an issue as a page refresh when changing between pages will remove it. However, now the web is full of one-page applications you can see how this quickly becomes a problem.

The best way to clear your timers is by adding them to an array, then when you think is best, usually the start of a new animation, or just before a js page transition. Clear said timers and reset the array.

Michael Tempest

About Michael Tempest

Michael Tempest is the Lead Front End Developer at RefME. His passions are cycling, skiing, music and all things design / development related.

Recent Features

  • By
    Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event...

  • By
    Responsive and Infinitely Scalable JS Animations

    Back in late 2012 it was not easy to find open source projects using requestAnimationFrame() - this is the hook that allows Javascript code to synchronize with a web browser's native paint loop. Animations using this method can run at 60 fps and deliver fantastic...

Incredible Demos

  • By
    Record Text Selections Using MooTools or jQuery AJAX

    One technique I'm seeing more and more these days (CNNSI.com, for example) is AJAX recording of selected text. It makes sense -- if you detect users selecting the terms over and over again, you can probably assume your visitors are searching that term on Google...

  • By
    Multiple Background CSS Animations

    CSS background animation has been a hot topic for a long time, mostly because they look pretty sweet and don't require additional elements.  I was recently asked if it was possible to have multiple background animations on a given element and the answer is yes...with...

Discussion

  1. Mike

    It’s worth noting that simply hitting the “record heap snapshot” button a few times will send you on a wild goose chase. You want to force garbage collection between snapshots by clicking the trash can. You only have a memory leak if the snapshot size increases despite garbage collection.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!