The async attribute of the script tag. JavaScript Asynchronous Loading - Speed ​​Up Page Loading

Synchronous scripts are bad, they force the browser to block the construction of the DOM tree: first you need to get the script, execute it, and only after that continue processing the rest of the page. This is of course not news to you, and the reason why we, as evangelists, have promoted the use of asynchronous scripting. Here is a simple example:

<script src =>script > <script > var script = document .createElement("script"); script.src= "http://somehost.com/awesome-widget.js"; document .getElementsByTagName("head").appendChild(script);script >

What is the difference? In the "bad" version, we block the construction of the DOM tree, wait for the script to load, execute, and only then continue processing the rest of the document. In the second example, we immediately start executing a script that creates a script element pointing to an external resource, add it to the document, and continue processing the DOM. The distinction is subtle but very important: dynamic generated scripts not blocking.

So, that's great, right? Dynamically generated scripts are a thing! Not so fast.

Inline JavaScript has a small but important (and often overlooked) pitfall: CSSOM blocks it before it is executed. Why? The browser does not know what exactly such a script is planning to do, and since JavaScript can manipulate CSS properties, it blocks and waits while the CSS is parsed and the CSSOM is built. It is better to see once than hear a hundred times, consider the following example:

Wait a second, what's going on? Both scripts will be preloaded and executed ~2.7 seconds after the page is loaded. Note that the scripts will still only run after the CSS is available (~2.7 seconds), but because the scripts are already loaded when the CSSOM becomes available, we can execute them immediately, saving over a second of processing time. Did we do everything wrong?

Before we answer this question, let's look at another example, this time with the "async" attribute:

<script src= "http://udacity-crp.herokuapp.com/time.js?rtt=1&a" async >script > <script src= "http://udacity-crp.herokuapp.com/time.js?rtt=1&b" async >script >

If the async attribute is present, the script will be executed asynchronously as soon as it is available. If the attribute is absent, ... then the script is loaded and executed immediately before any further parsing of the document continues.

The async attribute on the script tag implements two important properties: it tells the browser not to block DOM building, and not to block scripts before CSSOM is built. As a result, scripts are executed immediately after they are loaded (~1.6 seconds), without waiting for CSSOM. Short list of results:

So why have we suggested so far to use a template that uses dynamically generated scripts?

Original article: Script-injected "async scripts" considered harmful Article read by: visitorFM , zenwalker , FMRobot

Hello friends! Did you know that JavaScript loading is one of the biggest bottlenecks in website performance? Today my main task is to explain what a script is and how it affects the speed and performance of the site.

A browser that loads a script tag stops rendering the page until the script is loaded and executed. The page is blocked and the browser does not respond to user actions for a couple of seconds. The delay time depends on several factors:

  • configuration ,
  • internet connection speed,
  • file size and more...

For this reason, the Google PageSpeed ​​Insights website speed analyzer recommends that you remove the blocking JavaScript code from the top of the page. It is good practice to place scripts at the bottom of the site, for example, before the closing tag or setting up asynchronous loading.

If the script code affects the display of the top part of the site, do not take it out separate file, but embed directly in the HTML.

JS can change the content of the site and even redirect to a different URL. In this case, including the script at the end of the document will cause the page to "twitch" by loading new or changing existing elements at the top.

Applying the async and defer attributes to the script tag

Let's understand what is asynchronous and deferred JavaScript work and what is the fundamental difference between async and defer attributes. But first, let's consider the sequence of processing a document with a normal connection of the script tag.

< src="example.js">

In an illustrative example, I will use the following conventions:

- page processing
- script loading
- script execution

Thus, the processing sequence is as follows:

The parsing of the HTML code is interrupted while the script is being loaded and executed, after which it continues. There is a delay in displaying the web page.

defer attribute

The defer attribute allows the browser to start loading js files in parallel without stopping further page processing. They are executed after full parsing document object model (from the English Document Object Model, abbreviated as DOM), while the browser guarantees consistency based on the order of connecting files.

< defer src="example.js" >

async attribute

Support for the async attribute was introduced in HTML5, it allows the browser to load js files in parallel and execute immediately after loading, without waiting for the rest of the page to be processed.

< async src="example.js" >

Processing sequence diagram:

This is an asynchronous download. The attribute is recommended for scripts that do not significantly affect the display of the document. These include statistics collection counters (Google Analytics, Yandex Metrica), advertising network codes (Yandex Advertising Network, Google adsense), buttons social networks and so on.

Website loading speed is one of the ranking factors in Google.

Asynchronous JavaScript connection reduces page load times by eliminating latency. Along with this, I recommend compressing and merging js files into one, for example, using the . Users like fast websites 😎

Async and Defer - JavaScript loading strategies


JavaScript is an integral part of any modern web application, and the strategies we choose to use for loading directly affect the performance of that very application. In this article, we'll try to understand the important differences between each approach, the pros and cons along with the performance implications, and how to optimize for page interaction and load time.

To demonstrate, I will create a website consisting of the following external dependencies. Pay special attention to the respective file sizes, as the download time of the files is directly proportional to this.

  • HTML - page ~ 1 MB. Contains the actual markup/content to show some dynamic output from JavaScript.
  • Image - image1.png ~ 5 Mb
  • JavaScript - file1.JS ~3MB is the core (main file) of javascript and depends on HTML parsing. It is needed in order to show some dynamic content or mount a react/angular component on the page.
  • JavaScript - file2.js ~460B - A small, independent javascript file that interacts with the dom.
  • JavaScript - file3.js ~ 1.5 MB is a secondary js file and depends on file1.js to execute some lower priority code. This code is not immediately required for page rendering and user interaction; it shows social media icons, comments, online help, running some analytics tasks, etc.
Now it's time to analyze different approaches

Approach-1 [scripts in head section]

In the first case, we will load all the scripts tags into the head section of our HTML. Below is a screenshot of network analysis chrome tabs page ready for user interaction.

Pros:

The code execution order of the various JS files will be preserved in the order in which the files were included in the HTML. In the current example, even if file2 and file3 were loaded before file1, the execution order would be correct.

Minuses:

In this scenario, HTML parsing will pause until all 3 scripts in the head section have been loaded, parsed, and executed. Empty White screen will be shown to the user even if the HTML file has already been loaded [but not parsed]. This is definitely not good for usability.

None of the above scripts will be able to access/manipulate the HTML page as the DOM is not ready yet. One of possible solutions The way to handle this issue is to listen for the DOMContentLoaded event and then execute the code after that. The DOMContentLoaded event is fired when the original HTML document has been completely loaded and parsed, without waiting for stylesheets, images, or images to finish loading.

Approach-2 [scripts at the end]

To overcome the 2 problems we face in the first approach, let's load all 3 scripts at the bottom of the body tag.

Pros: The HTML is parsed before the scripts are loaded, so the user will be able to see the actual content right away instead of having to wait for the scripts.

Since all scripts are executed after parsing the HTML, they can all access the DOM for any manipulation. The sequence of script execution is preserved.

Minuses:

There is no performance gain per se.

Approach-3 [using Async attribute]

HTML5 introduced the async script attribute, which helps in loading the appropriate script files in parallel on another thread without affecting the HTML parsing.

However, the corresponding script will be parsed and executed as soon as it finishes loading, whether or not the HTML parsing is completed, and will have a reference to the DOM element up to that particular point.

Here you can clearly see that file2.js was loaded before HTML file. However, while the browser was downloading file2, it did not pause the HTML parsing and because of this, by the time it was executed - it had a reference to the html placeholder to inject dynamic content.

Pros: Since the scripts are loaded on a different thread, HTML parsing will not be paused and the user will be able to see the actual content instead of a white blank screen. The main performance gain i.e. DOMContentLoaded time decreased from 47.68 seconds to just 21.12 seconds and represents a ~55% gain.

Minuses:

JS execution sequence is not preserved. It is executed in the appropriate load order, not an included sequence of scripts within the HTML. Browser Support - Not supported on older web browsers, i.e. IE 9 and below.

What happens if JS is loaded before DOM element will be available? An error will be thrown.

Note: placing scripts with an async attribute at the bottom of the body section would be useless and equivalent to approach-2.

Approach-4 [using the Defer attribute]

The defer attribute will cause the script to be executed only after HTML parsing has been completed. One very important point to consider here is that Chrome doesn't yet support deferral and has no effect on DOMContentLoaded duration. However, it executes scripts at the end of the HTML parsing.

Pros:

The script import sequence is preserved. So file3.js is only executed after the download is complete and file1 is executed, even if file3 was loaded earlier.

Browser support - it has the best support browsers compared to the async attribute, i.e. partially supported in IE v6-9

Scripts can access the DOM since it is only executed after the full HTML has been parsed.

Minuses:

I originally thought the delay would be the best choice than async, but later discovered that Chrome doesn't support it yet [version 71.0.3578.98] and has no effect on DOMContentLoaded duration.

However, it works as expected in Firefox with significant performance improvements.

conclusions

It is preferable to place script tags in the async head section for third-party libraries that depend on Google Analytics, Google reCAPTCHA, or anything else that doesn't require DOM access, as the corresponding scripts are loaded in parallel but executed immediately.

Use defer for all other scripts loaded in the head section, as they will also be loaded in parallel, but will only be executed after the HTML parsing has completed and the DOM is ready to be accessed/manipulated.

You can also use a combination of DOMContentLoaded listener inside asynchronous scripts to execute functionality later. Please leave your opinions and findings in the comments and I will be happy to discuss them with you.


The author of this material is I - Yuriy Pakholkov. I provide services for writing programs in Java, C ++, C # (as well as consulting on them) and creating websites. I work with sites on CMS OpenCart, WordPress, ModX and self-written. In addition, I work directly with JavaScript, PHP, CSS, HTML - that is, I can finalize your site or help with web programming.

The HTML

And the following examples show how to put (an inline) script inside the

module fallback

Browsers that support the module value for the type attribute ignore any script with a nomodule attribute. That enables you to use module scripts while also providing nomodule -marked fallback scripts for non-supporting browsers.

Specifications

Specification Status Comments
HTML Living Standard
The definition of"

In the oldest versions of IE (6 and below), asynchronous loading unfortunately does not work, but there are practically no such users anymore. All other browsers and services successfully use modern fast download web pages.

Internet