As more and more sites evolve into "Web 2.0" apps, the amount of JavaScript increases. this is a performance concern because scripts have a negative impact on page performance. mainstream browsers (I. e ., IE 6 and 7) block in two ways:
- Resources in the page are blocked from downloading if they are below the script.
- Elements are blocked from rendering if they are below the script.
With more and more websites involving "Web 2.0" applications, the number of JavaScript scripts has also increased dramatically. This is worrying because the script has a negative impact on the page performance. Mainstream browsers (such as IE 6 and 7) may experience blocking in the following two ways:
- If resources are located below the script, they will be blocked for download.
- If the elements are located below the script, they will be blocked for rendering.
The Scripts Block Downloads example demonstrates this. it contains two external scripts followed by an image, a stylesheet, and an iframe. the HTTP waterfall chart from loading this example in IE7 shows that the first script blocks all downloads, then the second script blocks all downloads, and finally the image, stylesheet, and iframe all download in parallel. watching the page render, you'll notice that the paragraph of text above the script renders immediately. however, the rest of the text in the HTML document is blocked from rendering until all the scripts are done loading.
The Scripts Block Downloads example shows the above situation. It contains two external scripts, followed by one image, one style sheet, and one iframe. The HTTP waterfall graph using IE7 to load this example shows that the first script blocks all downloads, the next 2nd scripts block all downloads, and finally the image style sheet and iframe are loaded concurrently. Observe the page rendering and you will find that the text above the script will be rendered immediately. However, other text in the HTML document is blocked until all scripts are downloaded.
All scripts in IE6 7, Firefox 2 3.0, Safari 3, Chrome 1, and Opera will be blocked for download.
Browsers are single threaded, so it's understandable that while a script is executing the browser is unable to start other downloads. but there's no reason that while the script is downloading the browser can't start downloading other resources. and that's exactly what newer browsers, including Internet Explorer 8, Safari 4, and Chrome 2, have done. the HTTP waterfall chart for the Scripts Block Downloads example in IE8 shows the scripts do indeed download in parallel, and the stylesheet is stored in that parallel download. but the image and iframe are still blocked. safari 4 and Chrome 2 behave in a similar way. parallel downloading improves, but is still not as much as it cocould be.
If the browser is single-threaded, it is understandable that the browser cannot download other resources when a script is being executed. But there is no reason to explain that when the script is downloaded, the browser cannot download other resources. Downloading scripts and downloading other resources in parallel are the functions implemented by all the latest browsers, including Internet Explorer 8, Safari 4, and Chrome 2. The HTTP waterfall diagram of the Scripts Block Downloads example in IE8 shows that the script is indeed downloaded in parallel, and the style sheet is also downloaded in parallel, however, the image and iframe are still blocked. The behavior of Safari 4 and Chrome 2 is similar. Parallel download has improved some of the results, but it has not yet achieved the best results.
In IE8, Safari 4, and Chrome 2, scripts are still blocked.
Fortunately, there are ways to get scripts to download without blocking any other resources in the page, even in older browsers. Unfortunately, it's up to the web developer to do the heavy lifting.
Fortunately, even in older browsers, there are ways to prevent scripts from blocking other page resources. Unfortunately, it depends on whether web developers are willing to undertake these heavy tasks.
There are six main techniques for downloading scripts without blocking:
- XHR Eval-Download the script via XHR and eval () the responseText.
- XHR Injection-Download the script via XHR and inject it into the page by creating a script element and setting its text property to the responseText.
- Script in Iframe-Wrap your script in an HTML page and download it as an iframe.
- Script DOM Element-Create a script element and set its src property to the script's URL.
- Script Defer-Add the script tag's defer attribute. This used to only work in IE, but is now in Firefox 3.1.
- Document. write Script Tag-Write the <script src = ""> HTML into the page using document. write. This only loads script without blocking in IE.
The following are six non-blocking Script Loading Techniques:
- XHR Eval-download the script through XHR and execute it through eval.
- XHR Injection-download the script through XHR, inject the page by creating a DOM element of the script, and set the text attribute.
- Script in Iframe-contains scripts on an HTML page and is loaded using iframe.
- Script DOM Element-create a script DOM Element and set the src attribute to the Script url.
- Script Defer-added the defer attribute of the Script. Once only available in IE, now Firefox 3.1.
- Document. write Script Tag-use document. write <script src = ""> On the HTML page. Valid only for IE.
You can see an example of each technique using Cuzillion. it turns out that these techniques have several important differences, as shown in the following table. most of them provide parallel downloads, although Script Defer and document. write Script Tag are mixed. some of the techniques can't be used on cross-site scripts, and some require slight modifications to your existing scripts to get them to work. an area of differentiation that's not widely discussed is whether the technique triggers the browser's busy indicators (status bar, progress bar, tab icon, and cursor ). if you're loading multiple scripts that depend on each other, you'll need a technique that preserves execution order.
In Cuzillion, you can see a sample of each technology. It turns out that there are important differences between these technologies, as shown in the following table. Most of them provide parallel downloads. Some technologies cannot be used in Cross-Domain Scripting, and some must be simply modified based on your existing scripts, there is also an unwidely discussed distinction between whether to trigger the busy indicator of the browser (Status Bar, progress bar, label icon and cursor ). If you need to load multiple interdependent scripts, you also need a technology to maintain the execution sequence.
Technical name |
Support parallel download |
Supports cross-domain names |
No need to modify the script |
Indicates whether there is a busy schedule. |
Guaranteed execution sequence |
Size (bytes) |
XHR Eval |
IE, FF, Saf, Chr, Op |
No |
No |
Saf, Chr |
- |
~ 500 |
XHR Injection |
IE, FF, Saf, Chr, Op |
No |
Yes |
Saf, Chr |
- |
~ 500 |
Script in Iframe |
IE, FF, Saf, Chr, Op |
No |
No |
IE, FF, Saf, Chr |
- |
~ 50 |
Script DOM Element |
IE, FF, Saf, Chr, Op |
Yes |
Yes |
FF, Saf, Chr |
FF, Op |
~ 200 |
Script Defer |
IE, Saf4, Chr2, FF3.1 |
Yes |
Yes |
IE, FF, Saf, Chr, Op |
IE, FF, Saf, Chr, Op |
~ 50 |
Document. write Script Tag |
IE, Saf4, Chr2, Op |
Yes |
Yes |
IE, FF, Saf, Chr, Op |
IE, FF, Saf, Chr, Op |
~ 100 |
The question is: Which is the best technique? The optimal technique depends on your situation. this demo-tree shocould be used as a guide. it's not as complex as it looks. only three variables determine the outcome: is the script on the same domain as the main page, is it necessary to preserve execution order, and shocould the busy indicators be triggered.
Question: Which is the best technology? The best technology depends on your situation. The decision tree below can serve as a guide. It looks complicated, not actually. Only three parameters determine the output result: whether the script is under the same domain name on the home page, whether to ensure the execution sequence, and whether to trigger the busy indication mark.
Ideally, the logic in this demo-tree wocould be encapsulated in popular HTML templating ages (PHP, Python, Perl, etc .) so that the web developer cocould just call a function and be assured that their script gets loaded using the optimal technique.
Ideally, the logic of this decision tree will be reflected in popular HTML template languages (PHP, Python, Perl, etc.). Therefore, WEB developers can simply call a function, they can ensure that their scripts use the best technology to load scripts.
In syntax situations, the Script DOM Element is a good choice. it works in all browsers, doesn' t have any cross-site scripting restrictions, is fairly simple to implement, and is well understood. the one catch is that it doesn' t preserve execution order should SS all browsers. if you have multiple scripts that depend on each other, you'll need to concatenate them or use a different technique. if you have an inline script that depends on the external script, you'll need to synchronize them. I call this "coupling" and present several ways to do this in Coupling Asynchronous Scripts.
In many cases, using the Script DOM Element is a good choice. It can work in all browsers without any cross-origin restrictions, and is easy to implement and be understood in code, the only drawback is that not all browsers can maintain the correct execution order. If you have multiple scripts that are mutually dependent, You need to merge them or use other technologies. If you have inline scripts on the page that depend on external scripts, you must synchronize them, I call this method "coupling" and propose some methods to achieve this in the coupled asynchronous script.