Async vs Defer - Which Script Tag is More Efficient When Loading JavaScript?

Async vs Defer - Which Script Attribute is More Efficient When Loading JavaScript?

JavaScript is the most popular language in the world. Why? Because its the only well adopted language supported by a Web Browsers that brings dynamics to frontend experience.

Because of that, almost any web application requires from developers to write at least a bit of JavaScript code. While it's not a problem (unless you hate this language 😉), some of us tend to create very complex, frontend heavy applications that load.. well, definitely not fast.

In this article, you'll get familiar with async and defer - two attributes that will speed up your website speed rendering.

Table of contents

    How website rendering works?

    Have you ever wondered how web browsers render websites?

    There are a couple of steps which have to be taken by browser engine to display web page:

    1. Receiving raw bytes of data from the server and transforming them into characters with proper encoding.
    2. Parsing characters to extract HTML structures. Without this process data returned from a server would be just a bunch of meanless characters. This step is called tokenization, and it produces tokens.
    3. Converting tokens into nodes - distinct objects with properties.
    4. Linking nodes to create data structures, known as DOM (Document Object Model) and CSSOM (CSS Object Model).

    There is one important website optimization rule that applies to this process - ensuring that both the HTML and CSS are delivered to the browser as quickly as possible. In other words, you don't want to interrupt the process of constructing Object Model in any way (learn more about this process).

    What's the actual speed problem when loading JavaScript?

    To understand why these four steps are important in terms of JavaScript load time let's take a look at a typical scaffold of HTML code:

       <!-- Meta tags, Links, etc -->
       <script type="text/javascript" src=[link-to-script]></script>
       <!-- Your website content -->

    During the process of building the DOM structure, the browser will send a request to fetch any related resources that your website links to.

    In this case, we are linking to the external JavaScript code. Let's remap rendering timeline for this example:

    Script rendering in head with no attribute

    As you can see, the DOM object (which is a final result of the fourth step described before) is not ready until the JavaScript code is fetched and executed. Why is this a very bad case scenario? Because user is not going to see a website until the browser engine finishes building DOM.

    And it's not only JavaScript dependencies that delay DOM ready state. It's also CSS, images, videos, etc. Browser engine has to load all resources first, to finish rendering.

    Developers often move JavaScript eternal scripts to the bottom of the page in the following way:

       <!-- Meta tags, Links, etc -->
       <!-- Your website content -->
       <script type="text/javascript" src=[link-to-script]></script>

    Since most of the time your JavaScript code will manipulate the body contents, it makes sense to place scripts at the end of the body tag.

    Before the web engine reaches this point, it's already able to render most of the page content, which is a good thing since the user will be able to see the website before JavaScript execution.

    Script rendering in body with no attribute

    Is there any downside to this solution? If the script uses document.write to insert part of the page's content, it can't be moved lower in the page, therefore, you can't place it at the end of the body tag.

    Also, keep in mind that it doesn't affect document.ready state because the browser has not yet finished building DOM.

    To sum up, we are able to render page faster, but we still have to wait for scripts to be loaded synchronously.

    Meet async attribute for external scripts

    In the typical case scenario, when the browser engine meets the following script:

    <script type="text/javascript" src=[link-to-script]>

    it stops further processing to download and execute JavaScript code.

    You can speed it up with async attribute:

    <script type="text/javascript" src=[link-to-script] async></script>

    Once again, let's illustrate in timeline how your website is going to rendered by browser engine, but in this case, with async attribute:

    Script rendering in body with async attribute

    As you can see, we can save time previously spent on the script download process. With async, browser engine is fetching the script asynchronously in parallel, and once the download is completed it immediately stops further operations to execute JavaScript code.

    With a lot of script tags included in your HTML, async attribute saves a lot of time. Just imagine being able to download 10 scripts in parallel while the browser engine is busy building the rest of DOM.

    Is this a perfect solution? Not really. While we can save time on the download process, we are not exactly sure when each of the scripts will be executed.

    Also, if your JavaScript code depends somehow on the DOM object it might try to modify its structure before it's complete. Of course, you can fix this step with events, but it would be nice to somehow make it work more in a more efficient way.

    Meet defer attribute for external scripts

    It's as easy as in case of async to add defer attribute to your JavaScript tag:

    <script type="text/javascript" src=[link-to-script] defer></script>

    Let's visualize how the process of rendering DOM will look like with defer attribute:

    Script rendering in body with defer attribute

    The problem we had with the async attribute is gone with defer. JavaScript code is being fetched in parallel and executed exactly after the browser engine is finished parsing HTML.

    It's what we needed since the website, in this case, is displayed to the user without two big latency sources:

    • downloading external JavaScript code,

    • executing fetched code during DOM render.

    Is defer and async a holy grail for JavaScript load speed?

    As with everything in web programming, there are no holy grails. Why? Because of browser versions support.

    You can check the current support here:

    Should you care? Well, there might be some bugs in older browsers, like the one with defer in IE9, but unless you need to support these cases, you should go with defer for most of the time, since it brings the fastest way to load DOM in the browser.


    Async and defer are great script tag attributes that allow you to speed up building the DOM. Since in SEO speed matters, you should be using them to rank higher in SERP.

    If you're not technical, and you own website based on Wordpress, worry not - there are a lot of plugins out there for async script loading.

    How do you load JavaScript code on your website? Let us know in the comments if adding defer or async improved your page load speed.

    Download our ebook
    Szymon Soppa Web Developer
    Szymon Soppa Curiosum Founder & CEO

    Read more
    on #curiosum blog

    Phoenix LiveView Tutorial: Adding Phoenix PubSub and Pow Authentication to Messenger

    We've already bootstrapped our Phoenix LiveView-based Messenger app's database structure and a first LiveView page.

    This time, we're going to improve real-time communication between the app's users using Phoenix PubSub, and use the Pow library to add secure user authentication.

    As of November 2020, the latest Phoenix LiveView version is 0.14.8 - and the series has been updated to match it!

    5 top-tier companies that use Elixir

    Elixir is a pretty capable language - and it consistently ranks near the top of most loved and wanted languages rankings. It has a large following and some very persuasive preachers as well. But that would not be enough to make me like it – what I need as real proof of its strengths is real businesses that strive with Elixir.

    That’s what this list is all about – a bunch of stories from top companies that chose Elixir and never looked back. Let us show you how its power and versatility shows in practice.