When the page loads, the browser should say “I don’t know what ‘x-deferred-script’ is, and therefore ignore the concents of the script tag. You eval it manually later on, using something like eval($("script#greeting").html()); This is similar to Google’s trick of embedding Javascript in comments, but has the additional benefit of keeping Javascript where it should be, in a script tag. This way, it plays nicer with code editors (e.g. Vim happily handles syntax highlighting) and analytical tools. (Technically, those tools should probably do the same as browsers and not treat anything inside a script tag as Javascript, but fortunately for us, they do.)

Script Islands are useful in the following situations:

With a complex web app – lots of Javascript – where you want it to load quickly and without lots of processing or round-tripping back to the server. Sometimes, it’s a better user experience to load the lot in one go, show something, and eval() the rest of the Javascript once the basic app is running (perhaps in anticipation of a separate “page” or another part of the application). This is a special case of Predictive Fetch; it makes sense Google would use (a variant of) Script Island for the mobile edition of GMail, where round trips to and from the server are expensive.

With a single-page application (SPA) like TiddlyWiki, where all the code is inside the HTML file. Each of the script islands is a separate module, and a microkernel is responsible for loading the scripts according to different rules. For example, the scripts might contain “depends” attributes to declare they depend on other scripts, so the microkernel sequences the script loading. Or another scenario might be that the user has some control over which scripts get loaded; instead of deleting the other scripts from the file, you keep them around in case the user wants to repackage the SPA, with a different set of scripts.

BTW I originally used <script src=""> to trick the browser into not evaluating the script tag’s innerHTML. Thanks to Jeremy for coming up with the more elegant alternative of a type=x-tiddler (which I stated above in the more generic form type=x-deferred-script).

3 thoughts on Design Pattern: Script Islands

Why would you choose eval over injecting a SCRIPT tag though – because of the async nature?
I wonder whether CommonJS et al.’s require function could be made to work with this technique… (I don’t see why not, so I’ll probably look into it.)

“defer” and “async” I covered in the scalecamp slides (http://softwareas.com/whats-new-in-on-demand-javascript-scalecamp-presentation). It’s a good point that “defer” might be used as an alternative to a script island in some situations. However, I can see the need for script islands where “defer” isn’t supported or more fine-grained control is required, e.g. the case with tiddlywiki and plugin dependencies.

G’Day

Welcome to Michael Mahemoff's blog, soapboxing on software and the web since 2004. I'm presently using HTML5 and the web to make podcasts easier to share, play, and discover at Player FM. I've previously worked at Google and Osmosoft, and built the Ajax Patterns wiki and corresponding book, "Ajax Design Patterns" (O'Reilly 2006).
For avoidance of doubt, I'm not a female, nor ever have been to my knowledge. The title of this blog alludes to English As She Is Spoke, a book so profoundly flawed it reminded me of the maturity of the software industry when this blog began in 2004. I believe the industry has become more sophisticated since then, particularly the importance of UX.
Follow @mahemoff