Defer vs Async JavaScript and how this affects the Core Web Vitals

Learn when to async JavaSCript and when to defer it for the best Core Web Vitals results

Arjen Karel Core Web Vitals Consultant
Arjen Karel
linkedin

Defer vs Async JavaScript and how this affects the Core Web Vitals

In this article I will show the difference between defer vs async JavaScript and why this affects the Core Web Vitals 

Whenever I audit the Core Web Vitals of a client I often find that there is little distinction on a page between parser blocking (sync), asynchronous or deferred JavaScript. That is a shame because different scripts have different optimal timings. 

In Short:

'Normal' JavaScript in the head of the page is executed before the parsing of the html starts, async scripts do not block the start of the parsing but are executed as soon as they are downloaded. Deferred scripts are executed after the page has been parsed. 

In general, the async attribute is a good choice for scripts that do not need to interact with the DOM, such as scripts that load images or videos. The defer attribute is a good choice for scripts that need to interact with the DOM, such as scripts that initialize widgets or add event listeners. Omit both if your script makes massive changes to the visible viewport.

defer vs async vs sync script timelines

1. Synchronous JavaScript (Sync):

By default JavaScripts in the head of the page are synchronous scripts.When JavaScript code is executed synchronously, it immediately blocks the browser's main thread until the script is fully executed. This means that the browser must wait for the JavaScript code to finish before proceeding with other tasks, such as rendering the DOM. As a result, synchronous JavaScript can significantly impact page speed and responsiveness, especially for larger and complex scripts. When a page contains synchronous JavaScript, the browser cannot load other resources or render the page until the JavaScript is executed, leading to potential delays in page loading.

<!DOCTYPE html>
<html>
<head>
  <title>Sync JavaScript Example</title>
  <script src="script1.js"></script>
  <script src="script2.js"></script>
</head>
<body>
  <!-- Page content here -->
</body>
</html>

2. Asynchronous JavaScript (Async):

Asynchronous JavaScript allows the browser to continue executing other tasks while the script is being downloaded in the background. By using the async attribute in the <script> tag, developers indicate that the script is not dependent on the DOM and can be executed independently. The browser does not wait for the async script to finish loading before continuing with the rendering of the page. As a result, async scripts have the potential to improve page speed, especially on slower connections, as they do not block the critical rendering path.

<!DOCTYPE html>
<html>
<head>
  <title>Async JavaScript Example</title>
  <script src="script1.js" async></script>
  <script src="script2.js" async></script>
</head>
<body>
  <!-- Page content here -->
</body>
</html>

It is important to note that async scripts may fire in an unpredictable order, as they execute as soon as they are available, regardless of their order in the HTML document. If scripts depend on one another, using async may cause dependency errors.

3. Deferred JavaScript:

Deferred JavaScript, indicated by the defer attribute in the <script> tag, allows scripts to be downloaded in the background while the browser continues parsing the HTML document. Similar to async, deferred scripts do not block the critical rendering path, leading to faster page loading. However, the key difference is that deferred scripts maintain their execution order, executing in the order they appear in the HTML document. Deferred scripts are executed after the DOM is fully parsed and just before the DOMContentLoaded event is fired.

<!DOCTYPE html>
<html>
<head>
  <title>Defer JavaScript Example</title>
  <script src="script1.js" defer></script>
  <script src="script2.js" defer></script>
</head>
<body>
  <!-- Page content here -->
</body>
</html>

Using defer is beneficial for scripts that rely on the DOM and need to be executed in a specific order, as it ensures that the necessary DOM elements are available when the script runs. This can be advantageous for scripts that perform DOM manipulation or have dependencies on other scripts.

Attribute When the script is loaded When the script is executed
none In the background Before constructing the DOM
async In the background Immediately after loading
defer In the background After the rest of the page has been parsed, in the order that it appears in the HTML

How do async and defer improve Page Speed?

Synchronous JavaScript (Sync) can significantly slow down page loading and make the website less responsive, especially if the scripts are large or take a long time to execute.

Asynchronous JavaScript (Async) can improve page speed by allowing independent scripts to load in parallel with other resources. However, care must be taken to manage dependencies correctly to avoid unexpected behavior.

Deferred JavaScript can also improve page speed by not blocking the critical rendering path. It ensures that the DOM is ready before executing scripts that rely on it, leading to a more predictable and controlled execution order.

Best Practices:

  • Use asynchronous (async) for independent scripts that do not rely on the DOM and can be executed out of order.
  • Use deferred (defer) for scripts that depend on the DOM and need to execute in a specific order, especially when performing DOM manipulation.
  • Avoid using synchronous JavaScript whenever possible, as it negatively impacts page speed and user experience.

By using the appropriate loading technique for JavaScript files, you can optimize page speed, improve user experience, and ensure smoother interactions on their websites. Understanding the differences between sync, async, and defer and their implications on page loading is essential for building performant web applications.

Please note that the effectiveness of using sync, async, or defer attributes may vary based on the specific context and content of the website. Regular testing and performance analysis are crucial to fine-tune the page loading strategy and ensure optimal results for different scenarios.

Taking it a step further, load scripts on demand

Async and defer can speed up a page by not blocking the parser, but it's important to note that 'deferring scripts' will not solve all your issues. For example, the largest contentful paint element is vulnerable to network and CPU competition caused by deferred and async scripts. The interaction to next paint is also affected by scripts that execute early during page load. That's why, whenever possible, you should load scripts on demand to have more control over their impact on page performance. Curious? Read how we load scripts on demand

I help teams pass the Core Web Vitals:

lighthouse 100 score

A slow website is likely to miss out on conversions and revenue. Nearly half of internet searchers don't wait three seconds for a page to load before going to another site. Ask yourself: "Is my site fast enough to convert visitors into customers?"

Defer vs Async JavaScript and how this affects the Core Web VitalsCore Web Vitals Defer vs Async JavaScript and how this affects the Core Web Vitals