作者:煭敻 | 来源:互联网 | 2023-09-12 21:02
有人翻译成了中文,不知道好不好没看,不想看英文的可以看这里:
http://www.cnblogs.com/yslow/archive/2009/04/29/1446236.html
This post is based on a chapter from Even Faster Web Sites, the follow-up to High Performance Web Sites. Posts in this series include: chapters and contributing authors, Splitting the Initial Payload, Loading Scripts Without Blocking, Coupling Asynchronous Scripts, Positioning Inline Scripts, Sharding Dominant Domains, Flushing the Document Early, Using Iframes Sparingly, and Simplifying CSS Selectors.
Much of my recent work has been around loading external scripts asynchronously. When scripts are loaded the normal way ( The way his implementation works is that the inlined code is only executed after the external script is done loading. There are several benefits to coupling inline and external scripts this way:
- simpler - one script tag instead of two
- clearer - the inlined code’s dependency on the external script is more obvious
- safer - if the external script fails to load, the inlined code is not executed, avoiding undefined symbol errors
It’s also a great pattern to use when the external script is loaded asynchronously. To use this technique, I had to change both the inlined code and the external script. For the inlined code, I added the third line shown above that sets the script.text
property. To complete the coupling, I added this code to the end of “sorttable-async.js”:
var scripts = document.getElementsByTagName("script");
var cntr = scripts.length;
while ( cntr ) {
var curScript = scripts[cntr-1];
if ( -1 != curScript.src.indexOf('sorttable-async.js') ) {
eval( curScript.innerHTML );
break;
}
cntr--;
}
This code iterates over all scripts in the page until it finds the script block that loaded itself (in this case, the script with src
containing “sorttable-async.js”). It then evals the code that was added to the script (in this case, “sorttable.init()”) and thus bootstraps itself. (A side note: although the line of code was added using the script’s text property, here it’s referenced using the innerHTML property. This is necessary to make it work across browsers.) With this optimization, the external script loads without blocking other resources, and the inlined code is executed as soon as possible.
Lazy Loading
The load time of the page can be improved even more by lazyloading this script (loading it dynamically as part of the onload handler). The code behind this Lazyload version just wraps the previous code within the onload handler:
window.onload = function() {
var script = document.createElement('script');
script.src = "sorttable-async.js";
script.text = "sorttable.init()";
document.getElementsByTagName('head')[0].appendChild(script);
}
This situation absolutely requires this script coupling technique. The previous bootstrapping code that called “sorttable.init()” in the onload handler won’t be called here because the onload event has already passed. The benefit of lazyloading the code is that the onload time occurs even sooner, as shown in Figure 3. The onload event, indicated by the vertical red line, occurs at ~320 ms.
Figure 3: Lazyloading HTTP waterfall chart
Conclusion
Loading scripts asynchronously and lazyloading scripts improve page load times by avoiding the blocking behavior that scripts typically cause. This is shown in the different versions of adding sorttable to UA Profiler:
- Normal Script Tags - 487 ms
- Asynchronous Script Loading - 429 ms
- Lazyloading - ~320 ms
The times above indicate when the onload event occurred. For other web apps, improving when the asynchronously loaded functionality is attached might be a higher priority. In that case, the Asynchronous Script Loading version is slightly better (~400 ms versus 417 ms). In both cases, being able to couple inline scripts with the external script is a necessity. The technique shown here is a way to do that while also improving page load times.