Javascript. 6 tips to improve the performance of the code you write

List of tips that are easy to implement on a day-to-day basis to help you write more optimized Javascript code

If you’ve made it this far, I’m sure you already have some practice developing with Javascript. As you may have seen, it is a very open language: Javascript imposes very few restrictions on working with it. That is why I think that from time to time it is very interesting to stop, take a breath, and review some very easy-to-follow recommendations to write much more optimized code.

I have compiled some of the techniques that I use the most in this article. I hope you find them useful and of course, I will be happy to read yours in the comments. As I always say, it is about continuing to learn together.

Let’s go there!

Compute only once

function calculateSomethingHeavy() {
...
}
function foo(bar) {
const result = calculateSomethingHeavy();
// do something with result and bar
}
foo(1);
foo(2);

Here for example every time we invoke the foo function we are invoking the calculateSomethingHeavy function although it does not depend on the arguments.

Another simpler example that illustrates this case well is:

function foo(bar) {
const object = { key: 'value'};
// do something with bar
}
foo(1);

Here every time we invoke foo we are creating the same object over and over again, with the consequent expenditure of memory.

The solution to this problem is to use “closures” that allow us to remember those values so that we are not forced to recalculate them every time:

function calculateSomethingHeavy() {
...
}
function fooCreator() {
const result = calculateSomethingHeavy();
return foo(bar) {
// do something with result and bar
}
}
const foo = fooCreator();foo(1);
foo(2);

Or even use the modulo pattern:

const module = (function foo(bar) {
const object = { key: 'value'};
// do something with bar
return {
doSomething: function(bar) {
// do something with bar
}
}
})();
module.doSomething(1);

Use native methods

The most common case is usually that of performing operations on an array of elements to which we apply a function: you are still surprised to see the following piece of code but I promise you that it is very common:

function applyFunctionToArray(arr, fn) {
const newArray = [];
for (let i = 0; i < arr.length; i ++) {
const result = fn(arr[i]);
newArray.push(result);
}
return newArray;
}

If you pay attention, you will realize that it is a very generic implementation of the Array.prototype.map method that allows us to apply a function to the elements of an array and generate a new one with the results.

That piece of code, which, as I said, is not that difficult to find on the way, has a much worse performance than working with map directly. Publicizing this type of functions that Javascript implements natively is one of the reasons why every Wednesday I share a “javascriptera recipe”: we often reinvent the wheel without knowing that Javascript already gives us what we want.

Avoid “delete”

Therefore, the recommendation is that whenever we can assign undefined to the key that we want to eliminate so that the performance of the object in memory is not affected:

const obj = { 'foo': 1, 'bar': 2, 'zeta': 3};
obj.foo = undefined;

The other alternative is to use the “rest” operator to eliminate the key that we do not want, however this form is slower than delete itself, so it is not worth it:

const obj = { 'foo': 1, 'bar': 2, 'zeta': 3};
const {foo, ...objectWithoutFoo} = obj;

Split your code

This is greatly influenced by the size of the JS files that the browser has to download and how optimized the application code is.

Thanks to the magic of Webpack and other code “packers” it is very easy to divide the application into different pieces that the browser requires as the user browses the web without having to download “the entire application”.

But the benefits of Webpack do not end there, it is also capable of performing an operation called “tree shaking” to eliminate dependencies that we are not using and that we often import without realizing it:

My advice is that you familiarize yourself with these concepts because they help to have much lighter and faster applications.

Not everything has to be flat objects

For example, “Sets” allow us to have arrays without duplicates and Maps and Weak Maps offer interesting benefits when working with key-value objects:

That is why I want to encourage you from time to time to dig a little deeper into these types of objects that Javascript provides natively, since many times they will allow us to optimize certain pieces of our code.

To show a button. Thanks to the “Sets” eliminating duplicates from an array is as simple as this:

const arr = [1, 2, 1, 2, 3, 4];
const arrayWithoutDuplicates = [...new Set(arr)];

And to finish … take care of the libraries / packages you use

Examples of these types of libraries are Lodash or MomentJS. In the case of the first one, many times we bring it to perform operations that Javascript can already perform natively.

In the case of the latter, its creators recommend using much more optimized alternatives, such as one of my recent discoveries: the Date-FNS library.

Final thoughts

Also, if you are curious to compare how fast different implementations of the same logic work, you can consult the JSBench.me tool:

Written by

Entre paseo y paseo con Simba desarrollo en Symfony y React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store