The guide to non-blocking code on the web

In this article we’ll give a run down of what non-blocking is, how it can help you improve performance on your site, and maybe even get that sweet, sweet 100 on performance in Google Lighthouse.

(All examples will be JavaScript/node related)

What is blocking code?

Blocking code is any code that prevents the execution of further code, such as a resource heavy for/while that isn’t being executed asynchronously (we’ll get to what that is a bit later).

A good example of what may constitute blocking code is an operation that accesses an external api or database; doing this in a single thread will force all the other code to wait for that execution to finish, which can be a pain if you need to perform other operations or animations. Blocking code has the potential to noticeably slow your site down if the operation being performed is a lengthy one.

Asynchronous vs synchronous

So you may be asking what is the difference between asynchronous and synchronous ( which I’ll be calling async and sync from now on for brevity).

To put it simply, sync code is like a single lane country road – nobody can overtake, and speed is dictated by the leading vehicle (or in our case, code execution).

Async, on the other hand, is like a motorway which initially only has one lane BUT drivers (operations/functions etc) can add their own lanes, up to an infinite number of lanes (using promises and callbacks), or until your computer catches fire.

So just to recap: sync = single lane country road. Async = magically expanding motorway.

Promises promises

JavaScript promises are a very nice way of firing and chaining async operations.

First, you declare your promise with your function nested inside, or as a callback. Then, you call the promise with .then() appended as the next action to call when the promise is successful, or .catch() to handle errors, and .finally() to be performed regardless of whether or not the execution was successful.

Here’s a simple example;


Request animation frame

Now when it comes to JavaScript, I’m not a huge fan of using it for animating. Most animations are fairly simple and can be performed using CSS alone (with keyframes and a bit of checkbox magic).

However, there are definitely uses for firing animations using JavaScript; chaining separate animations, executing based on states or events unknown to CSS. So, when you need to use JS to animate something use the lovely requestAnimationFrame() method! This method takes a callback that contains all your pretty animations as an argument and then makes a very polite request to the window to execute your animations before the next repaint.

This means that the animation will execute at the best possible time and not block up your other operations!

Async script and defer

Finally, let’s talk about the somewhat-related async and defer attribute on script tags.

Adding defer to your script tag loads the contents of the tag after the DOM has finished parsing, meaning the script will have access to all the DOM elements.

This is perfect for non-essential animations or interactions. Async is for tags when they’re availability it not a primary concern (3rd party analytics etc). Using this allows the DOM and other tags to load, and executes the tag whenever it’s ready.



Here are two examples of Google Lighthouse performance audits. The first is a site that used all the nice non-blocking methods, including requestAnimationFrame() and async and defer scripts;


and the second, was not;



As publishers and website creators seek to stand out from the crowd, we’re unlikely to see the average page weight significantly reduced any time soon. Making your code as efficient as possible not only helps your users and their bandwidth, but can also help you gain search engine traffic as the major operators tend to reward lean sites over their heavier, slow-loading competitors.

Get it right, and your efforts will receive their maximum potential reward.

Leave a Reply

Exclusive tips, how-tos, news and comment

Receive monthly updates on the world of mobile dev.

Other Products

Market leading device intelligence for the web, app and MNO ecosystems
DeviceAtlas - Device Intelligence

Real-time identification of fraudulent and misrepresented traffic
DeviceAssure - Device Verification

A free tool for developers, designers and marketers to test website performance
mobiReady - Evaluate your websites’ mobile readiness

© 2024 DeviceAtlas Limited. All rights reserved.

This is a website of DeviceAtlas Limited, a private company limited by shares, incorporated and registered in the Republic of Ireland with registered number 398040 and registered office at 6th Floor, 2 Grand Canal Square, Dublin 2, Ireland