Design Pattern: Script Islands

“Script Island” is what I’m calling a design pattern I alluded to here. The pattern is to embed Javascript in your HTML like so:

  1. <script id="greeting" type="x-deferred-script">
  2.   alert("this is my script - it's eval'd on demand");
  3. </script>

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

  1. Pingback: What’s New in On-Demand Javascript? ScaleCamp Presentation

  2. This is interesting stuff indeed!

    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.)

    Also, what do think of HTML5’s defer attribute in this context?

  3. @FND Updated the post, hopefully it’s clear now. The async nature is the reason indeed.

    “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.

Leave a Reply