Running scripts in WebKit
Posted by Tony Gentilcore on Friday, September 17th, 2010 at 10:10 amWebKit nightly builds now support the HTML5 async
and defer
script attributes. This makes it easier for web pages to load faster by downloading JavaScript without blocking other elements of the page.
Normally when the parser encounters an external script, parsing is paused, a request is issued to download the script, and parsing is resumed only after the script has fully downloaded and executed.
During the download the browser is blocked from doing other useful work, such as parsing HTML, executing other scripts and performing layout. Although partially mitigated by WebKit’s preload scanner, which speculatively looks ahead for resources to download during the down time, network latency still slows down some pages.
There are many techniques for working around this performance bottleneck, but they all involve extra code and browser-specific hacks. Instead, scripts which do not require synchronous execution can now be marked as either async
or defer
. Here’s how they work.
Both async
and defer
scripts begin to download immediately without pausing the parser and both support an optional onload
handler to address the common need to perform initialization which depends on the script. The difference between async
anddefer
centers around when the script is executed. Each async
script executes at the first opportunity after it is finished downloading and before the window
’s load
event. This means it’s possible (and likely) that async
scripts are not executed in the order in which they occur in the page. The defer
scripts, on the other hand, are guaranteed to be executed in the order they occur in the page. That execution starts after parsing is completely finished, but before the document
’s DOMContentLoaded
event.
Here is an example of an external script which takes 1 second to download followed by an inline script which takes 1 second to execute. We can see that the page loads in about 2 seconds.
Here is the same example, but this time the external script is deferred. Since the second script can execute while the first is downloading, the page now loads about twice as fast.
In addition to upcoming versions of WebKit-based browsers, Firefox has long supported the defer
and onload
attributes and support for async
was added in version 3.6. Internet Explorer has also long supported the defer
attribute. While async
is not yet supported, support for the onload
attribute was added in version 9.