JavaScript Optimization Tips To Improve Performance in 2024

JavaScript Optimization Tips To Improve Performance in 2024

JavaScript is a truly amazing tool for front-end programming, creating interactive, feature-rich websites and fast, seamless web applications. Every front-end developer knows JavaScript, but when used without caution or expertise, it can be a double-edged sword. Poorly written JavaScript code can slow your website, negatively affecting load times and rendering speed. In this article, we’ll cover some useful tools to help you avoid the “dark side effects” of JavaScript.

1. Order in which elements are loaded

First, it’s important that all elements in the <head> section are pre-loaded, before the visitor sees anything in-browser, then all subsequent elements are ordered to load in a logical way. Any JavaScript inside the <head> section can slow down a page’s rendering. Here’s a look at the difference between an optimized and an unoptimized page load:</head></head>

Optimized


When an unoptimized page is loading, chances are a user will see a “white screen” before the full page is then loaded. An optimized page load (render actually) happens in a more step-by-step way, allowing a user to see some content gradually until the page loads fully.

Why is the load order important?

With a little research via Google, we can see how load order impacts user focus:

Order

Google calls this the RAIL model.

2. Minify JavaScript code for smaller file sizes

Minifying code is different from obfuscating code, but both are methods of transforming JavaScript—to be more difficult to read, or to make it smaller. Minification accomplishes the latter, and can shrink file sizes to decrease page load times.

Line breaks, additional spaces, comments etc.—all of this increases the size of a JavaScript file and affects the speed of page load. Compressing the code solves this issue well. Machines are not sensitive to the visual style of code like a human would be. Computers can read and launch minified code, even if all of your Javascript fits in just one string.

3. Optimize Javascript with minification

Optimization is a special type of JavaScript minification. These kind of minimizers not only delete unuseful white spaces, commas, comments etc. but also help to avoid “dead code”:

  • Google Closure Compiler
  • UglifyJS
  • Microsoft AJAX Minifier

How does optimization work? Here’s an example:

Before optimization:

--CODE language-markup language-js line-numbers--
function test(node) {
var parent = node.parentNode;
if (0) {
alert( "Hello from the other side" );
} else {
alert( "We love Upwork" );
}
return;
alert( 1 );
}


After optimization:

--CODE language-markup language-js line-numbers--
function test(){alert("We love Upwork")}

What exactly did optimization accomplish?

  1. The variable parent will never need to be used, so it gets deleted;
  2. False if() {…} is deleted as ‘dead code’; true else leaves only one possibility.
  3. Return is deleted; it’s also dead code.

4. Asynchronous loading of JavaScript: Defer and Async tags

Asynchronous loading of JavaScript is a type of sync loading. It means that your website loads in a multi-streamed way.

Javascript


When the browser finds the string with <script src="some.js"></script>, it will stop creation of DOM and CSSOM models while the JavaScript is executed. This is why most JavaScript code is located after the main HTML code.

To understand this point a little better, take a look at this code:

-- CODE language-markup line-numbers --
<html>
<head>
<script src="big.js"></script>
</head>

<body>
 This text will not be present until big.js is loaded.
</body>
</html>

Instead, you can add an async tag to the JavaScript so that creation of the DOM model happens in parallel, and won’t be interrupted while the JavaScript is loading and executed.

Use caution if your JavaScript must make some manipulations to the HTML or CSS, or if you’re loading a script in a strong order (e.g., jQuery-dependent libraries).

For example, if you’re using the very popular bxSlider on your website and like CDN for jQuery, to add bxSlider you could add this code to your HTML:

--CODE language-markup line-numbers--
<!-- jQuery library (served from Google) -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<!-- bxSlider Javascript file -->
<script src="/js/jquery.bxslider.min.js"></script>
<!-- bxSlider CSS file -->
<link href="/lib/jquery.bxslider.css" rel="stylesheet">

As you can see, jQuery is loading from the Google CDN but bxSlider is local. If we add an async tag to the string, which includes jQuery, it may create errors with the bxSlider if jquery.bxslider.min.js is loaded before jquery.min.js. In this case, order is very important so another tag is needed: defer.

If the browser sees a defer tag with JavaScript code, it will not stop loading the DOM and CSSOM models. All scripts with a defer tag will be loaded and run immediately after the DOM and CSSOM models are completed. Any scripts will be loaded in the order you code.

--CODE language-markup line-numbers--
<script src="1.js" defer></script>
<script src="2.js" defer></script>

In this case, 2.js will not be loaded until 1.js is loaded, and so on.

Important! Defer and Async tags are available only for external scripts (with src=”” tag). If you try to use them for internal scripts like <script>…</script> tags, defer and async will be ignored.

5. Exclude unused components of .js libraries

Events

Most developers use libraries like jQuery UI or jQuery Mobile as is. This means that the code includes all possible components of each library, when you may only need two or three. A similar situation occurs with other JavaScript libraries as well. If you have the ability to manage what components will be included in your package of library, definitely do it. Your website will load much faster, and your visitors will get a better experience.

Visit the Download Builder of jQuery Mobile or jQuery UI to create your own package of those famous libraries.

6. Use the HTTP/2 protocol

This second, encrypted version of the main Internet protocol can provide you with a lot of cool features, including the asynchronous download of external files, most notably JavaScript. While HTTP requires deep learning and an advanced knowledge of JavaScript theory, HTTP/2 can make JavaScript load faster.

Http

Use this website to get your own experience with HTTPS and HTTP/2. Another one test is Aka`mai HTTP/2 demo.

Http 1

7. Use a JavaScript content delivery network (CDN)

A CDN is not a panacea. For example, if your project is not worldwide and you opt to use a CDN that doesn’t have a local server in your country (e.g., the Russian Federation), this will increase page load time. Using a CDN is supposed to make things run faster, but in certain cases, it can have the opposite effect.

Akamai Dynamic Delivery

Akamai

You can use Cedexis to generate reports that compare various CDNs to help you to decide which provider is most affordable for your use case. Also, you can get more comparisons of CDNs here.

JavaScript CDN comparison chart

Javascript CDN

The above reports provide you with CDN comparison information, such as support for instant setup and different types of pricing. To get an idea of which CDN is best for your library, check out thousands of options at this site.

8. Gzip module for Apache, Nginx, and Node.js

Gzip is an amazing technology created back when the internet wasn’t as high-speed as it is today. Archivators were a popular technology (they’ve since decreased in popularity since USB flash drives can give up to 1TB of storage). The idea was to use Archivators for Internet web traffic (similar to creating files of websites), so gzip was developed to deflate files on web servers, compressing static (textual) files down to 99% of their original size. Because JavaScript is a textual file, gzip can be used to compress JavaScript files and also help to decrease page load times. Check to see if your web server technology has support for gzip here:

Gzip

There are modules for some of the most famous web servers, including Apache and Nginx.

Because JavaScript can be used not only for front-end development but back-end development as well (thanks to Node.js), you can compress JS files with the zlib module for Node.js.

t’s super fast and easy to set up:

--CODE language-markup language-js line-numbers--
const zlib = require('zlib');

Use it a few ways, like the following:

--CODE language-markup language-js line-numbers--
const gzip = zlib.createGzip();
const fs = require('fs');
const inp = fs.createReadStream('input.txt');
const out = fs.createWriteStream('input.txt.gz');

inp.pipe(gzip).pipe(out);

9. Position CSS and JavaScript code in <head>

This technique helps your page load faster, but requires pretty good knowledge of DOM and SCCOM. The idea is to bring a minimum amount of CSS and JavaScript code to the <head></head> section so it loads it immediately, while the more extensive code is stored in separate .css and .js files, like usual.

10. Where you can, use CSS3 effects in place of JavaScript

Older versions of CSS like 1.0 or 2.0 were not as powerful on their own and required a bit more JavaScript to create more advanced styling effects. But CSS 3.0 is a very capable language on its own, with lots of added functionality that requires less JavaScript. Another benefit is that CSS can be pre-compiled so CPU usage for CSS is lower than JavaScript.

For example, you can add sliders like CSSSlider in CSS3 and HTML5 without any JavaScript at all like. Here’s another free one to try:

HTML:

--CODE language-markup line-numbers--
<!DOCTYPE html>
<html lang="en"></html>
<head></head>
<meta charset="UTF-8">
<title>CSS Slider</title>

<body></body>
<base href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/">
<div id="slider"></div>
<figure></figure>
<img src="austin-fireworks.jpg" alt="">
<img src="taj-mahal_copy.jpg" alt="">
<img src="ibiza.jpg" alt="">
<img src="ankor-wat.jpg" alt="">
<img src="austin-fireworks.jpg" alt="">

CSS:

--CODE language-markup language-css line-numbers--
@keyframes slidy {

0% { left: 0%; }
20% { left: 0%; }
25% { left: -100%; }
45% { left: -100%; }
50% { left: -200%; }
70% { left: -200%; }
75% { left: -300%; }
95% { left: -300%; }
100% { left: -400%; }
}

body { margin: 0; }
div#slider { overflow: hidden; }
div#slider figure img { width: 20%; float: left; }
div#slider figure {
position: relative;
width: 500%;
margin: 0;
left: 0
text-align: left;
font-size: 0;
animation: 30s slidy infinite;

}

Watch a demo here.

11. Memory leaks

A memory leak refers to a situation where an application finishes using memory but does not return it back to the underlying OS to be used by another application or process. Every time you create an object or variable in JavaScript, memory is consumed. JavaScript memory leaks occur when you are technically finished with an object or variable but the JS runtime still thinks you need it.This can cause a drag on system performance as resources that should otherwise be freed up for other processes and applications are no longer available.

The best way to avoid JavaScript memory leaks is to properly manage your scope. Here are some common examples of how memory leaks occur in JavaScript:

Accidental global variables

Globally scoped variables are accessible to all scripts and functions in a JavaScript document. For this reason global variables are not automatically cleaned up by JavaScript’s garbage collector. It’s important to use global variables sparingly and to remember to manually null or reassign them after use.

Hanging outer-function variables in closures

A closure is a function that is nested within a function—in other words, an inner or enclosed function. Closures have access to the variables and scope of the outer function. Similar to accidental global variables, it’s possible for a function declared in the outer scope to still be residing in memory after the outer function has executed because some inner function still has access but isn’t using it.

Detached DOM/Out of DOM references

The document object model (DOM) is a doubly-linked tree in which any reference to any node in the tree will prevent the entire tree from garbage collection. A detached DOM occurs when a node is removed from the tree but is still retained in memory by a reference within JavaScript. If you don’t handle the reference in JavaScript, the garbage collector will not sweep the reference and your code will continue to consume memory.

12. Limit variable calls

Declaring variables and calling back on them for references is the bread and butter of coding. But as we discussed previously everytime JavaScript holds a reference to a variable, memory is consumed, and the potential for memory leaks increases. As we already covered above, accidental global variables, hanging closures, and Out of DOM references can all have the potential to impact performance via memory leaks.

Simply limiting the number of variable calls can lead to writing more concise performant code. If you find yourself declaring too many variables, consider if there is a better way to write your function to achieve the same result with better performance.

13. Reduce DOM and access size

The Document Object Model or DOM is a data representation of the objects that make up the structure of a web page. All web pages are documents (usually HTML) and every object within a document is called a node. JavaScript manipulates the DOM and its nodes directly to change structure, style, and content in response to user input.

Every time your JavaScript code accesses a DOM element or makes a change to the DOM, depending on what you’re doing, you trigger a re-render of part or all of the document. This uses memory and can slow performance if your system has to recalculate lots of nodes within a large DOM.

Trimming large DOM trees is a good place to start when optimizing front-end code. Benefits of keeping your DOM small include:

  • Improved network efficiency and load performance
  • Better runtime performance (i.e., less DOM nodes to access, recompute, or style)
  • Reduced risk of memory leaks (i.e., easier to avoid Out of DOM references).

Ways you can minimize your DOM include:

  • Keep CSS rules simple
  • Minimize DOM references
  • Avoid complex animations or remove them from the flow
  • Limit the number of DOM elements affected by a change through componentization.

14. Code splitting

Code splitting is the practice of splitting your code across functional components within smaller files that can be called on an as-needed basis. While the total amount of code is more or less the same as if you used a single JavaScript file, it replaces the load time of loading a single large JavaScript file with fractional load times for specific functions and features of your application. You can use a bundler like Webpack to split your code into chunks for app optimization.

15. Use Web Workers

Web Workers allow you to spawn new background threads to run scripts while the main application thread continues to serve the end user. This allows you to perform tasks in the background without interfering with the user interface while someone is using the application.

Technically speaking, a web worker is an object created using a constructor that runs a named JavaScript file containing the code that will run in the worker thread. The web worker is restricted from manipulating the DOM directly.

Benefits of web workers include:

  • Frees up resources for the single thread available to JavaScript applications.
  • Allows you to hide large, time-consuming tasks from the end user.
  • A quick work-around that approximates concurrent multithreaded JavaScript

16. Test your code

Measurement is the key to improvement. And it’s by testing your code that you can identify performance issues such as memory leaks and patch them. Here are some popular JavaScript testing tools:

Console.time()

Console.time() is a simple built-in JavaScript function that you can use to track how long an operation takes. At the start of your process simply call:


--CODE language-markup language-js line-numbers--
console.time(label);

Where “label” can be a unique name you provide your timer. At the end of your process you can call:

--CODE language-markup language-js line-numbers--
console.timeEnd(label);

Operation time will be tracked from start to end giving you the effective process time.

YSlow

YSlow is an open-source performance tool that analyzes your website and gives performance optimization tips. YSlow will call your website and compare its performance against Yahoo’s standards for high-performance websites. YSlow will provide you with a score between 0% and 100% and which rules affected your score. This is a good roadmap for optimizing your code for better performance.

JSFiddle.net

JSFiddle.net is a web development coding playground that runs in your browser.

It boasts:

  • Support for JavaScript, HTML, CSS, and CoffeeScript
  • Boilerplates for React, Vue, and jQuery
  • The ability to demo code snippets and share them for code collaboration
  • Simple bug-reporting for GitHub issues

Conclusion

As you can see, there are numerous technologies and techniques to help you with optimization of JavaScript code to speed up download and rendering times. If you’re looking to speed up your page load times with any of these popular optimization techniques, browse Upwork to find a skilled freelance JavaScript developer for the task.

Heading

asdassdsad
Projects related to this article:
No items found.

Author Spotlight

JavaScript Optimization Tips To Improve Performance in 2024
Yoshitaka Shiotsu
Technical Copywriter & SEO Consultant

Yoshitaka Shiotsu is a project engineer turned technical copywriter and SEO consultant who regularly contributes to the Upwork Resource Center. He specializes in helping tech companies, startups, and entrepreneurs set themselves up as voices of authority within their target industries.

JavaScript Optimization Tips To Improve Performance in 2024
Technical Copywriter & SEO Consultant

Get This Article as a PDF

For easy printing, reading, and sharing.

Download PDF

Latest articles

X Icon
Hide