Performant JavaScript Best Practices - Reduce dependencies and DOM interactions

John Au-Yeung - Jan 27 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Like any program, JavaScript programs can get slow fast if we aren’t careful with writing our code.

In this article, we’ll look at some best practices for writing fast JavaScript programs.

Reduce DOM Manipulation With Host Object and User’s Browser

DOM manipulation is slow. The more we do, the slower it’ll be. Since DOM manipulation is synchronous, each action is done one at a time, holding the rest of our program.

Therefore, we should minimize the number of DOM manipulation actions that we're doing.

The DOM can be blocked by loading CSS and JavaScript. However, images aren’t blocking render so that they don’t hold up our page from finishing loading.

However, we still want to minimize the size of our images.

Render blocking JavaScript code can be detected with Google PageSpeed Insights, which tells us how many pieces of render-blocking JavaScript code we have.

Any inline CSS would block the rendering of the whole page. They are the styles that are scattered within our page with style attributes.

We should move them all to their own style sheets, inside the style tag, and below the body element.

CSS should be concatenated and minified to reduce the number of the stylesheet to load and their size.

We can also mark link tags as non-render blocking by using media queries. For instance, we can write the following to do that:

<link href="portrait.css" rel="stylesheet" media="orientation:portrait">
Enter fullscreen mode Exit fullscreen mode

so that it only loads when the page is displayed in portrait orientation.

We should move style manipulation outside of our JavaScript and put styles inside our CSS by putting styles within their own class in a stylesheet file.

For instance, we can write the following code to add a class in our CSS file:

.highlight {  
  background-color: red;  
}
Enter fullscreen mode Exit fullscreen mode

and then we can add a class with the classList object as follows:

const p = document.querySelector('p');  
p.classList.add('highlight');
Enter fullscreen mode Exit fullscreen mode

We set the p element DOM object to its own constant so we can cache it and reuse it anywhere and then we call classList.add to add the hightlight class to it.

We can also remove it if we no longer want it. This way, we don’t have to do a lot of unnecessary DOM manipulation operations in our JavaScript code.

If we have scripts that no other script depends on, we can load then asynchronously so that they don’t block the loading of other scripts.

We just put async in our script tag so that we can load our script asynchronously as follows:

<script async src="script.js"></script>
Enter fullscreen mode Exit fullscreen mode

Now script.js will load in the background instead of in the foreground.

We can also defer the loading of scripts by using the defer directive. However, it guarantees that the script in the order they were specified on the page.

This is a better choice if we want our scripts to load one after another without blocking the loading of other things.

Minifying scripts is also a must-do task before putting our code into production. To do that, we use module bundlers like Webpack and Parcel, which so create a project and then build them for us automatically.

Also, command-line tools for frameworks like Vue and Angular also do code minification automatically.

Minimize the Number of Dependencies Our App Uses

We should minimize the number of scripts and libraries that we use. Unused dependencies should also be removed.

For instance, if we’re using Lodash methods for array manipulation, then we can replace them with native JavaScript array methods, which are just as good.

Once we remove our dependency, we should remove them from package.json and the run npm prune to remove the dependency from our system.

Poor Event Handling

Event handling code is always slow if they’re complex. We can improve performance by reducing the depth of our call stack.

That means we call as few functions as possible. Put everything in CSS style sheets if possible if we’re manipulating styles in our event handlers.

And do everything to reduce calling functions like using the ** operator instead of calling Math.pow .

Conclusion

We should reduce the number of dependencies and loading them in an async manner if possible.

Also, we should reduce the CSS in our code and move them to their own stylesheets.

We can also add media queries so that stylesheets don’t load everywhere.

Finally, we should reduce the number of functions that are called in our code.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .