Tips and tricks to increase performance and website load time

JavaScript has become one of the most popular programming languages of all time. It is used by almost 96% of websites all over the world according to W3Tech. One key fact you should know about the web is that you have no control over the hardware specifications of the devices your user would access your website on. The end-user may access your website on a high-end or a low-end device with either great or poor internet connection. This means that you have to make sure your website is optimized as much as possible for you to be able to satisfy the requirements of any user.

Here are a few tips for you to have a better-optimized JavaScript code that would result in greater performance.

As a side-note, make sure to share and reuse your JS components to keep the right balance between high-quality code (that takes time to produce) and reasonable delivery times. You can use popular tools like Bit (Github), to share components (vanilla JS, TS, React, Vue, etc.) from any project to one single component hub, without losing too much time over it.

1. Remove Unused Code and Features

The more code your application contains, the more data needs to be transmitted to the client. It would also require more time for the browser to analyze and interpret the code.

Sometimes, you might include features that are not used at all. It is better to keep this extra code only in the development environment, and not to push it for production so that you would not burden the client’s browser with unused code.

Always ask yourself whether that function, feature, or piece of code is a necessity.

You can remove unused code manually or by using tools such as Uglify or Google’s Closure Compiler. You can even use a technique called tree shaking which removes unused code from your application. Bundlers such as Webpack provide this technique. You can read more about tree shaking over here. If you want to remove unused npm packages, you can use the command npm prune . More info can be read from NPM docs.

2. Cache Whenever Possible

Caching increases the speed and performance of your website by reducing latency and network traffic and thus lessening the time needed to display a representation of a resource. This can be achieved with the help of the Cache API or HTTP caching. You might wonder what happens when your content changes. The above caching mechanisms are capable of handling and regenerating the cache when certain conditions are met such as the publishing of new content.

3. Avoid Memory Leaks

Being a high-level language, JS looks after several low-level management such as memory management. Garbage collection is a process common for most programming languages. Garbage Collection in layman terms is simply collecting and freeing back memory of which has been allocated to objects but which is not currently in use in any part of our program. In programming languages like C, the developer has to take care of memory allocation and deallocation using malloc() and dealloc() functions.

Even though garbage collection is performed automatically in JavaScript, there can be certain instances where it will not be perfect. In JavaScript ES6, Map and Set were introduced with their “weaker” siblings. This “weaker” counterpart known as WeakMap and WeakSet hold “weak” references to objects. They enable unreferenced values to be garbage collected and thereby prevent memory leaks. You can read more about WeakMaps here.

4. Try to Break Out of Loops Early

Looping for large cycles can definitely consume a lot of precious time. That is why you should always try to break out of a loop early. You can do this with the help of the break keyword and continue keyword. It is your responsibility to write the most efficient code.

In the below example, if you did not break from the loop, your code will run the loop 1000000000 times which is clearly in an overload.

let arr = new Array(1000000000).fill('----');
arr[970] = 'found';
for (let i = 0; i < arr.length; i++) {
  if (arr[i] === 'found') {
        console.log("Found");
        break;
    }
}

In the below example, if you did not continue when the loop does not match your condition, you will still be running the function 1000000000 times. We only process the array element if it is in even position. This reduces the loop execution by almost half.

let arr = new Array(1000000000).fill('----');
arr[970] = 'found';
for (let i = 0; i < arr.length; i++) {
  if(i%2!=0){
        continue;
    };
    process(arr[i]);
}

You can read more about loops and performance over here.

5. Minimize the Number of Times the Variables Get Computed

To reduce the number of times a variable gets computed, you can use closures. In layman terms, closures in JavaScript gives you access to an outer functions scope from an inner function. The closures are created every time a function is created-not called. The inner functions will have access to the variables of the outer scope, even after the outer function has returned.

Let’s see two examples to see this in action. These examples are inspired from Bret’s blog.

function findCustomerCity(name) {
  const texasCustomers = ['John', 'Ludwig', 'Kate']; 
  const californiaCustomers = ['Wade', 'Lucie','Kylie'];

  return texasCustomers.includes(name) ? 'Texas' : 
    californiaCustomers.includes(name) ? 'California' : 'Unknown';
};

If we call the above functions several times, each time a new object is created. For every call, memory is unnecessarily re-allocated to the variables texasCustometrs and californiaCustomers .

By using a solution with closures, we can instantiate the variables only once. Let’s look at the below example.

function findCustomerCity() {
  const texasCustomers = ['John', 'Ludwig', 'Kate']; 
  const californiaCustomers = ['Wade', 'Lucie','Kylie'];

  return name => texasCustomers.includes(name) ? 'Texas' : 
    californiaCustomers.includes(name) ? 'California' : 'Unknown';
};
let cityOfCustomer = findCustomerCity();
cityOfCustomer('John');//Texas
cityOfCustomer('Wade');//California
cityOfCustomer('Max');//Unknown

In the above example, with the help of closures, the inner function which is being returned to the variable cityOfCustomer has access to the constants of the outer function findCustomerCity() . And whenever the inner function is being called with the name passed as a parameter, it does not need to instantiate the constants again. To learn more about closures, I suggest you go through this blog post by Prashant.

#javascript #developer

14 JavaScript Code Optimization Tips for Front-End Developers
3.15 GEEK