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 😁?

Vuex is a state management pattern + library for Vue.js applications

What is Vuex?

Vuex is state management library for Vue.js. Basically, you have one central area (store) in your app that controls the global state.

Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion. – Vuex Docs

What is The View?

The View is a daytime talk show with various co-hosts. The View has seen its fair share of hosts come and go and we’ll be hearing their hot-takes on Vuex throughout this article.

vuex
Nicolle Wallace explains to the table, ‘If you are familiar with React and Redux you might find this analogy helpful – Vuex is to Vue applications as Redux is to React applications.’ She also explains that she used to co-host The View.

Why use Vuex?

Vuex is perfect tool to use when you have lots of components that all depend on the same information – instead of passing props around from parent to child and back again, the components can rely on getting the information they need from the Vuex store. Vuex makes it easy to access global state and update it – with predictable results.

Lisa Ling gives voice to your inner question, ‘But what if my app is pretty small? Only a couple components and very little state to manage? Is it really worth it to go through the trouble of setting up state management with Vuex?’ She also gives voice to your other inner question, ‘Did Lisa Ling used to be a co-host on The View?’. The answer is yes.

Rosie Perez replies, ‘Great point, Lisa. If you have a small application it probably isn’t worth setting up Vuex to manage global state. However, if you’re like me and have ever been 15+ components in with state flying around every which way you’ll see what a big difference to your sanity Vuex can make! You are also like me if you used to co-host The View! I’d say if you are building a medium or large sized app you should plan on using Vuex. That being said, if you are looking to practice you can set up Vuex in a smaller app to get a feel for how it works.’.

Setting up Vuex on your Vue project

Rosie O’Donnell addresses you in the audience to break down the steps, ‘Okay now I know you are all wondering how to get Vuex working with your application. First things first…’

  • Navigate to your Vue.js project directory (cd your-project-name) and run npm install vuex --save to install Vuex for your project
    Side note: Your project directory should include the following: index.html file containing an element with id=”app”, src folder that contains the App.vue and main.js files, the main.js file imports your App.vue file and sets up the Vue instance for your app.
  • Create a new store folder within your project’s src folder (mkdir store) and change directory to the new folder (cd store)
  • Create a file to set up your store (touch store.js) in your store folder
  • Create your Vuex Store
// This is in the store.js file
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex); // enable Vuex functionality in our application

export const store = new Vuex.Store({ // create Vuex Store
  state: {  
    exViewHosts: ['Nicolle Wallace','Lisa Ling','Rosie Perez'], 
    // include properties for your global state here
  }  
}) 
  • Import your Vuex Store in main.js to use in your application
// main.js file
import Vue from 'vue';
import App from 'App.vue';
import { store } from './store/store';

new Vue({   // create Vuex Store
  el: '#app',  
  store,  // es6 syntax --> equivalent to store: store
  render: h => h(App)
}) 
  • Access the store from your components
// This is from my App.vue file, you can access the store from any component though
<template>
  <div>
    <ul>
      <li :key="exHost" v-for="exHost in exHosts">{{ exHost }}</li>
    </ul> 
  </div>
</template>

<script>
  export default {
     computed: {
        exHosts() {
          return this.$store.state.exViewHosts; 
          // access the Vuex store with $store
        }
     }
  }
</script>

Star Jones has an important point for the audience, ‘Now before everyone gets too carried away, there is actually a lot more to the Vuex store than what Rosie has laid out. Getters, Mutations, and Actions are a big part of managing global state with Vuex and we’ll be discussing next week as part of our Hot Topics.’

In conclusion…

This has been a quick introduction to Vuex and I hope you’ve been inspired to try out Vuex to manage state in your next Vue.js application! For a more detailed look into all that Vuex has to offer, I recommend checking out the official Vuex Docs.

GitHub Pages and JavaScript and Putting Everything to Use

GitHub Pages and JavaScript

A long time ago I blogged about GitHubPages and getting started with setting up a webpage.

The static web pages are nice and they can help you make your project or documentation look good, but for a long time I wanted to take this a bit further.

First I wrote two prototypes:

  • One extending a GitHub Pages set up with JavaScript serving data from a local resource
  • Another one serving data from a remote resource

Both worked fine, but I wanted to extend this beyond the prototype stage. And I would LOVE to go crazy in a cool looking, super interactive solution, but I have to be honest:

  • I am not an experienced frontend developer
  • I am no web designer
  • And am by no means there yet, with my web and JavaScript skills

I feel over this nice article on Mozilla Developer Network (MDN) and I got an idea, something I could, something pretty basic I could do with my collection of “Today I Learned” notes. I could add some JavaScript to make it more interesting.

But there was and still is a lot of hurdles to get over to get to something working, so lets start at the beginning. GitHub Pages use Jekyll which is a static site generator written in Ruby. You can add themes to make it stand out and you can customize the layout using CSS (Sass) and by changing the HTML templates.

When wanting to play around with these themes what I have normally done was to clone the specific theme, like:

There a plenty of other themes to choose from and with customization, you are not stuck with the standard layout, which is a HUGE help if you like me, is not a web designer.

In the past I have made use of GitHub Pages and Jekyll for many of my projects and repositories, but mostly I have been in a situation where I had to commit, push and wait for me to see the changes applied – and this is not particularly gratifying. It can work for layout, but for coding, I must admit I would prefer something more coding environment like.

So when I started playing around extending the project with JavaScript, I would have to solve the problem on how to get feedback faster from my changes. I have previously used different hacks where I would render the relevant HTML and CSS in a browser based on files, but the changes where small and pretty basic. This did require some more and adoption of some new tools.

First, I need Jekyll running locally on MacOS and I wanted to get in a situation where I could simply do (lifted from: “Jekyll: Quickstart”):

$ bundle exec jekyll serve
$ open http://localhost:4000/

And then all the editing so I could see the result of my work and get feedback, prior to commiting and pushing…

Luckily I was able to locate good resources from the GitHub help pages, guiding me to get this working:

So this was basically the steps I took.

I am using rbenv, so I have a local Ruby installation for the project.

$ rbenv local 2.6.3

I created a Gemfile

$ cat Gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

# gemspec
gem "github-pages", group: :jekyll_plugins

I installed Jekyll and bundler

$ gem install jekyll bundler

And now I can run the site locally.

$ bundle exec jekyll serve

Pointing my favorite browser to: http://localhost:4000/

Next up was getting my head around the actual problem.

Since when we have is a HTML rendered from a Markdown file. We can control the CSS and do some extent the HTML. But as you can see from the (HTML skeleton)[https://github.com/jonasbn/til/blob/master/_layouts/default.html].

    <div id="content-wrapper">
      <div class="inner clearfix">
        <section id="main-content">
          {{ content }}
        </section>

Our main content is simply wrapped, so we are not able to control the translation from Markdown and the handling of the HTML layout for this part. We can apply CSS and make it look different, but we cannot control the data originating from the Markdown.

I searched for different approaches and with different words trying to find out how I could wrap a section indicating start and end of a part of the data and the closest I got was a jQuery solution, .wrapInner().

Unable to find a construct with exactly the capabilities I needed I ended up using a combination of document.querySelectorAll() and element.querySelectorAll().

Luckily I was able to identify all of the necessary elements relying on the <h3> tag.

document.querySelectorAll('h3').forEach(element => {
    count_tils(element);
});

Feeding the selected elements to my counter function:

function count_tils(element) {
    var sibling;

    if (sibling = element.nextElementSibling) {
        var list = sibling.querySelectorAll('li');
        if (list.length > 0) {
            var descriptor = 'tils';
            if (list.length == 1) {
                descriptor = 'til';
            }

            var text_content = element.textContent + ' (' + list.length + ' ' + descriptor + ')';
            element.textContent = text_content;

            total_tils += list.length;
        }
    }
}

I could select the <li> tags and sum them up. Do note the topmost line in the JavaScript file is:

var total_tils = 0;

As you can see the elements are added to the existing header (<h3>), by concatenating the count and a helpful string.

Now that I have the count I decided to do some more and I added it to the sidebar, which was carrying some text about the content on the page. This is together with a count of the categories,

The element for the sidebar was created using createElement and added using appendChild, which I found out how to do from a StackOverflow post.

var category_count = 0;

const count = document.createElement('p');
count.textContent = 'A collection of ' + total_tils + ' tils in total, split on ' + category_count + ' categories';

var sidebar = document.getElementById('sidebar');
sidebar.appendChild(count);

The implementation can be seen at and the JavaScript file, from where all of the above snippets come is available here.

It is quite a learning curve getting your head around all of the APIs, but as soon as you discover something and are able to add it to you tool box you can move on to new problems. The toughest issue is actually the nagging feeling whether you are using the right API or something more right is out there. The Mozilla Developer Network (MDN) is awesome as a resource, check it ouf if you are not familiar with it.