Improve the Performance of your JavaScript Web Application

JavaScript is one if not the most popular programming language in the world. Found in web pages, software, mobile apps, console applications, etc.

JavaScript is everywhere and it is definitely here to stay. The problem with this language is with its rise, a lot of applications that use it feel "janky" (slow). We are here today to try and optimize (reduce jank in) our JavaScript applications.

This doesn't seem bad, but with more expensive operations like checking if an element is in the viewport so we can animate, this becomes expensive with time and uses more memory.

A simple way to fix this is to either debounce or throttle the scrollHandler function. Wait, what?

It sounds complicated, but:

Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."

while

Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."

HTTP/2 is beginning to rise and unlike before where the best advice we got when serving JavaScript files was to combine our files into a large bundle, now we don't need to do that anymore.

HTTP/2 is multiplexed meaning that it's built to handle many file requests in a more optimal form. HTTP/2 can use one TCP connection to request many files unlike HTTP/1 where we had separate connections for each request. This makes HTTP/2 a lot faster when compared to HTTP/1 where we could only request files one at a time.

Free Node eBook

Build your first Node apps and learn server-side JavaScript.

📧

Thank you!

You have successfully joined the Scotchy super duper web dev awesome mailing list.

Thus serving up many files is now a good thing, as long as you are using HTTP/2. But not too much (too much of anything is bad).

If you use NPM to install dependencies, then you have a lot of junk in your build file. From a meme of Guy Fieri to localization files you "may" use.

Instead of including the entire codebase to use a part of it, just include what you need. Take Lodash for example, it comes with a lot of functions we may use, instead of keeping what we "may" use, why not require what we want.

Look at Facebook, Twitter, Instagram, 9gag, the list goes on when it comes to websites with infinite scrolling enabled. The problem with infinite scrolling is that the more dynamic content you add to the DOM, the more elements we have to query. This is bad for performance and quickly slows the browser by consuming memory (RAM).

9gag's approach to solving the problem of too many elements is quite cool. After reading a certain number of memes, 9gags shows you a button you can use to clear out memes you passed. If you click on the button, all the previous memes get deleted from the page and you begin to notice the site speed up.

9gag's solution is stellar, but another thing you can do is recycle DOM elements. You allocate some elements to use for displaying content to the DOM and when that elements exit the viewport, you take it back to the bottom as illustrated below.

There's this myth that JavaScript animations are slow. The truth is they are if not properly written same goes for CSS animations. But we can change that.

With requestAnimationFrame, we tell the browser to call a function to render a frame. The reason why this is so performant when compared to something like setTimeout is because it triggers the GPU for a faster and better rendering.

Thus making our animation render at 60fps (or a frame every 16.667ms) which is just perfect for the human eyes when it comes to speed it can comfortably understand.

To use it.

var start =null;var element = document.getElementById('SomeElementYouWantToAnimate');
element.style.position ='absolute';// Takes in the timestamp of the current framefunctionstep(timestamp){if(!start) start = timestamp;// calculate total time passedvar progress = timestamp - start;// get the number of pixels the element should move every frame
element.style.left = Math.min(progress /10,200)+'px';// only animate if time passed is lesser than 2000ms or 2 secondsif(progress <2000){
window.requestAnimationFrame(step);}}
window.requestAnimationFrame(step);

This feels like too much work just to make a box move left. But there are JavaScript libraries like Anime.js, Gsap that make animation a breeze.

One use of JavaScript service workers is to cache files for use offline. The thing is that the files are not only cached to be used offline, they can also be used when there is an internet connection. This helps your application skip the request for a JavaScript file and just fetch it from its cache which is definitely faster and better optimised when compared to fetching the file from the server.

Also, going offline gives your web app the feel of a desktop or mobile app (depending on the screen) which gives the illusion of a faster application.

JavaScript promises use a fluent API to describe code and being a native function, they are completely optimised and should be used frequently. The fact that promises are asychronous means they are not blocking thus improving the speed of your application

Chrome developer tools is a very robust range of tools. Apart from a console, DOM inspector, it also comes with a profiler.
Chrome developer tools is a very robust set. Apart from a console, DOM inspector, it also comes with a profiler (learn about Chrome's JavaScript Profiler).

Soon to be called "Memory Panel", this tool checks runs a series of tests on your web application and looks for memory leaks. If it discovers anything, it is then displayed in a graph, showing you potential bottlenecks and memory leaks.

After you fix these problems, you will definitely notice an improvement in your app performance and prevent JavaScript from quitting on you :).