Memory leak in JavaScript

I’ve been writing web applications for more than a decade. From classic ASP to PHPASP.Net web forms and the list goes on and on. However, something that’s been common between all those years for me has been to care about how performing the site is. One important part of that has been to look out for memory leaks, because they can cause the page to go super slow or even crashing in more serious scenarios.

Intro

Memory leaks are a common problem in software development, regardless of whether the language you’re using is memory managed or not. By that I mean languages which come with a garbage collector. Memory leaks happen when a piece of memory is allocated, but never freed by the application, and is not returned to the container app or the operating system.

I remember going through the concept in uni, but I can’t remember anything apart from the fact that usually there is a tree made up of all the occupied memory locations. Every time the garbage collector is looking into the memory parses that tree, and if a node is not connected to any branch, it gets recollected and returned to the main program.

Most of us web developers are likely to use one of the major frameworks or libraries to write our applications. Some maybe using a bit older languages like PHP or Ruby, but no matter what we use, there will be a high chance that we come face to face with this problem one way or another.

Consequences

So what happens when there is a memory leak in our applications 🤔?

In some cases the memory consumption just keeps going up. If the user is using a decent spec machine, they might not even realise it. Not everyone is obsessed like us developers checking their task manager often to see how much memory is consumed.

Regardless, it slows down the page, makes interactions not responsive, and might even cause the tab or the whole window to crash.

 

Memory leak in JavaScript

It’s way easy in JavaScript to allocate some memory and forget about it. Even if you’re not writing plain JavaScript, it’s still possible that a memory leak happen, without you noticing it.

But how does it happen?
In JavaScript there are a few possible ways a memory leak can happen.

  • Unintentionally creating global variables
  • Timers and callbacks
  • Out of DOM references
  • Closures
  • Event listeners

 

Out of DOM references (detached DOM)

When some nodes are removed from the DOM but still exists in memory through JavaScript, we have out of DOM references or detached DOM. Usually it means there is a reference to a variable which was referencing that node.

DOM is a doubly linked tree, meaning any reference to any node would mean the entire tree would not be garbage collected.

Doubly linked tree

Let’s go through an example to make this a bit more clear:

function create() {
  let ul = document.createElement('ul');
  ul.id = 'list';
  for (var i = 0; i < 10; i++) {
    var li = document.createElement('li');
    li.textContent = `Item # ${i}`;
    ul.appendChild(li);
  }
  return ul;
}

const list = create();

document.body.appendChild(list);

function deleteList() {
  document.body.removeChild(document.getElementById('list'));
}

document.getElementById('delete').addEventListener('click', deleteList);

Clicking the delete button, will remove the list from the DOM, but there is a reference in JavaScript, so the list never gets garbage collected. We could identify detached node using heap snapshots in your browser DevTools. I am using Chrome here, but you can use Edge (similar to Chrome), and Firefox too.

taking a heap snapshot

And once the snapshot is taken, type detached in the filter text box and you’ll see the detached DOM nodes.

See detached DOM nodes from heap snapshot

The way to fix these kind of issues is to always use local variables so that the reference is destroyed once the function execution is done.

Summary

We saw what will cause a potential memory leak in JavaScript and how to fix those issues, however, keep in mind that in most cases if you’re using a framework or library, these things are handled for you. If you’re using a library which you might suspect is causing memory leaks, you could easily find out using your browser DevTools memory profiler.

Hope this article has raised some awareness so that you can write more performing code and make user experience much better. No one wants to have their browser chew up memory like cheesecake right 😁?

Xamarin.Forms & Xamarin.Essentials Go AndroidX Avatar

Last week we released our official stable NuGet packages for AndroidX, which are an exciting replacement for the Android Support Libraries. AndroidX streamlines components into smaller and easier to update libraries for developers to consume. In the post last week, we also outlined several ways to start migrating your Android applications to take advantage of them. Today, I wanted to talk more about our upcoming plans for AndroidX for both Xamarin.Forms and Xamarin.Essentials.

Image Jetpack logo 2

Upcoming Releases

The upcoming releases of Xamarin.Forms 4.5 and Xamarin.Essentials 1.5, both in pre-release today, offer an upgrade path for developers creating Android apps. Both of the libraries will use AndroidX as their base when your application has its compile target set to Android 10. This means if you are currently compiling against and older version of Android your app will still receive the older support libraries when upgraded to these versions. To change your compile target, you can head into the project settings:

Project settings for Android 10

Once this version is set and you upgrade Xamarin.Forms or Xamarin.Essentials your app will start to use the AndroidX libraries and the migration support. This means even if you have other libraries still using older support libraries you should no problems.

Library Creators Call to Action

Right now is a great time to start upgrading your libraries to use AndroidX. I would recommend checking out the AndroidX pull request to Xamarin.Essentials as it shows you how to multi-target and support all versions of Android with a few lines of code. We recommend releasing new pre-release versions that base off of Xamarin.Forms 4.5 and Xamarin.Essentials 1.5 so all dependencies line up to help upgrades. It may also be helpful to create an issue and track AndroidX progress in your open source project and update the README with this information.

What’s Next?

The next stop for AndroidX is full integration throughout the Xamarin ecosystem. We hope that library creators start to adopt AndroidX so their users have a seamless transition and can start to slowly phase out the older support libraries. In an upcoming release of Visual Studio 2019 and Visual Studio 2019 for Mac you will see AndroidX used throughout all of the Android and Xamarin.Forms templates that use the latest versions of Xamarin.Forms and Xamarin.Essentials.

Custom AI-Assisted IntelliSense for your team

As you’ve been editing code, you may have noticed IntelliCode’s starred recommendations in your autocompletion lists. Our previous IntelliCode blog post explains that these smarter suggestions were machine-learned over thousands of open sourced GitHub repos. Using community knowledge is great for public APIs like the Standard Library, but what if you want IntelliCode recommendations for your APIs and other libraries that wouldn’t commonly be found in open-source code? To address this, in Visual Studio 2019 version 16.5 Preview 3 you can now train custom IntelliCode models on your own codebases. This generates something we call a “Team Completions model, because you’ll start to get recommendations based on your team’s coding patterns.  Continue reading “Custom AI-Assisted IntelliSense for your team”