Phase2Results.php" ); ?> Ajax Toolkit Caching - RuntimeWiki

Ajax Toolkit Caching

From RuntimeWiki

Jump to: navigation, search



Ajax Toolkit Caching

Detailed write-up


Using an Ajax toolkit rather than coding DHTML/Javascript from scratch is becoming the standard way of building Ajax web applications. A typical Ajax toolkit contains Javascript files, CSS files and images, with a typical download footprint ranging from 60KB to a few hundred kilobyes or even higher.

Today's browsers do have caching capability that automatically caches web content such as Javascript files. However, such caching behavior is not consistent and reliable. Web sites can not reliably leverage the default browser caching behavior to improve site performance. Further, such caching behavior does not differentiate different types of content, in terms of priority, frequency of use, etc. Ajax toolkits are becoming frequently used by web sites these days. Further, many different web sites use the same Ajax toolkit as the Ajax toolkit marketplace is converging onto a few top tier offerings.

Reliable caching of ajax toolkits in a cross-domain fashion will significantly improve Ajax web application performance.

Why Is This Important?

  1. Most of the Ajax enabled web applications using some kind of Ajax toolkit;
  2. A typical Ajax toolkit has a download footprint of 50KB to a few hundred or even higher kilobytes;
  3. The number of Ajax toolkits is converging onto a few leading ones, making these few leading ones highly frequently used Ajax toolkits over the web;
  4. Cross-domain caching of selected few leading Ajax toolkits will likely improve performance of thousands of Ajax enabled websites immediately;

Possible Solutions

Browser vendors to implement some reliable way of caching Ajax toolkits in a cross-domain fashion. In terms of which Ajax toolkits to cache and how to cache it, it is up to the indivisual browser vendors.

Background material that request this feature

  1. The Browser.Next, Alex Russell.


In this section, the contributors should express their opinions about this feature request, such as providing particular technical analysis or describing in prose why this feature is important (or not). It is recommended that each contributor create his own level-3 sub-section (e.g., === Jon Ferraiolo Comments ===).

Jon Ferraiolo's comments

If browsers include Offline Support, wouldn't that help address toolkit caching? I realize that the Offline Support would only cache on a per-domain/per-application basis, and therefore would require each separate application to download a particular Ajax toolkit anew, but at least the toolkit could be cached persistently for that particular web site. Attempting to cache toolkits locally on a cross-domain basis seems really complicated because of cross-domain security issues and complexities associated with various toolkits (e.g., the Dojo build process, which produces versions of Dojo that only contain the features needed by a particular application).

Douglas Crockford comments

I think that a hash cache could solve this, and it would an easy thing for each of the browsers to implement. It would add a hash= attribute to every tag that takes a url attribute. The url them becomes a hint to be used only if a file not matching the hash code is missing from the hash cache.

(reply from MatthewMastracci) The only issue with a hash cache is that it increases the value of a hash collision dramatically. A single collision would allow you to preload malicious cookie and password stealing on thousands of sites. And, as Bruce Schneier quotes the NSA: "Attacks always get better; they never get worse." Basically, if there's a cache, it'll have to be cryptographically signed.

Nicole Tedesco's comments: The JavaScript equivalent of the .jar or .cab library

(From NicoleTedesco)  Keep in mind that the total number (not just the instantaneous number) of HTTP connections invoked in the content load process has an enormous influence on response time as measured by the client. In short, this is because the act of establishing each connection is expensive in terms of time. The total number of HTTP connections can be reduced through a generalized resource bundling process.

For complex libraries like Dojo, Prototype and so on, I suggest doing for JavaScript toolkits what .jar files have done for Java or .cab files have done for .NET. Improvements to browser implementations (and, ideally, improvements to the HTML standard) can support the bundling of related resource files including JavaScript, images, sound, XML (XmlHttpRequest) or even other HTML pages (anchors and iframes) into a single compressed archive. These archive bundles could be linked to the parent HTML page through the <link> tag. Options could be provided to load these archives immediately (synchronously), in the background (asynchronously) and perhaps even deferred until after the body's onLoad event as been triggered. The archive bundles can be cached locally using the usual browser caching rules. When external resources are needed these archives will be searched first and content used directly if discovered.

Proposal details

  1. For security purposes, archive substitution may be limited to resources that would be located on the same server the parent HTML was originally loaded from
    1. Security could be enhanced however by recognizing digital signatures in these bundles, which could in turn enable additional options for secure consumption of cross-server scripts, content and related resources that would be desirable in many mashup scenarios
  2. Allow <link> tags to reference compressed archives on the server
    1. Default option is to load immediately and synchronously so that all references will be available when needed
    2. Optionally, the archive may be loaded asynchronously in a background thread
    3. Optionally, the archive may be loaded asynchronously after the body's onLoad event has been triggered ("deferred")
  3. Substitute archived content for matching external resources referenced in other tags such as anchors, script sources, images, iframes, objects and perhaps even XmlHttpRequests
    1. Determine the URI of the archived resource either by:
      1. ...concatenating the base URI of the archive to the relative path of the resource within the archive
      2. ...assuming all bundled resources are semi-absolute though protocol, server and port agnostic
      3. (one of the two methods above would need to be standardized upon, or an option to choose should be provided)
      4. (optional URL parameters should be ignored for matching, but provided to the script runtime as they are now)
  4. Provide options to page designers for handling background loads of archives
    1. Default is to substitute resource references as they are found in archives that have been loaded, decompressed and indexed; load remaining resources from the server after all archives have been likewise consumed
    2. Provide an option to always load a specific resource from the server, regardless of archive content
    3. Provide an option to load immediately if no currently consumed archive contains the content for that reference (a "high priority" option)
    4. Provide an option to associate specific resources to an archive, perhaps by connecting resource-dependent tags to the archive <link> through the link's id attribute; this could force a loading delay for that resource until that specific archive has been consumed and otherwise allow it to load immediately from the server and cached if that resource is not found within the referenced archive
  5. If an external resource is not found in any archive, it will be loaded and cached from the server as usual
  6. Provide options to control time stamp comparison/refresh logic
    1. Provide a "priority" option to the <link> tag to control refresh logic for all resources within that archive
    2. Provide a "priority" option for resources on a tag-by-tag basis (at the anchors, image inclusions and so on) for fine-grained control of refresh logic
  7. Support for offline browser operation can be enhanced through resource bundling such as this


In the example below, the linked resource bundle is loaded synchronously and is used to bundle the entire Dojo library and its associated resources. Resources are located on the server at:

  • /lib/
  • /img/logo.png

The archive has content:

  • /dojo is a directory
    • /dojo/dojo.js is a JavaScript file within the /dojo directory
    • Other files and directories exist as siblings to /dojo/dojo.js and subordinate to it
  • A /dijit/... hierarchy also exists
  • A /dojox/... hierarchy also exists
  • A /util/... hierarchy also exists

The image reference in the example's body section will be loaded using the usual logic assuming it will not normally be included as part of a Dojo Toolkit archive bundle.

HTML extension suggestions introduced in this example are:

  • The <link> rel attribute type of "Archive"
  • The optional archive attribute on the <script> tag (could also have been linkid or whatever)
  • The obviously non-standard djConfig attribute on the <script> tag, which is part of the Dojo Toolkit paradigm
      type="application/zip" />
      djConfig="parseOnLoad: true"
      archive="dojolib" />
    <img src="/img/logo.png" alt="Our logo" />

The archive attribute could alternatively work like a src attribute, using fragment notation to indicate the <link> identifier...

      djConfig="parseOnLoad: true"
      archive="#dojolib" />

...or provide convenient association to an archive without a <link> tag:

      djConfig="parseOnLoad: true"
      archive="/dojo/" />

(On the other hand, this might be a semantic bastardization that should be avoided—of this, I am not yet sure.)

Current support and HTML connection limits

Currently, some bundling occurs through the de facto standard of providing multiple scripts in a single script src statement to trigger HTTP/1.1 gzip server rules for ad hoc bundling. This fails however to support Dojo fetches of supporting scripts and localization files through the XmlHttpRequest process, or Google Maps fetches through the same mechanism. This proposed archive bundling mechanism could help alleviate these types of problems as well as alleviate the The Two HTTP Connection Limit Issue under various scenarios.

Convenience and complexity

This resource bundling solution may be inconvenient for simple "one-off" script inclusions, but it would be a lovely option to provide library developers who offer many scripts and resources and for those who already use a managed build process that create such archives as a matter of course (just as Java developers routinely produce .jar files). While one could argue that the complexities of implementing a generalized archive solution might seem like overkill if applied only to the support of JavaScript toolkit efficiency, but overall content creation complexity may be reduced because this approach can be applied without modification as a partial solution to other browser improvement requests:

Phase I Voting - Vote for Your Top 5 Features

NOTE: PHASE I VOTING IS NOW OPEN. (2008-04-01) We have now changed the voting procedure. Instead of putting votes on each separate wiki page, we are asking people to cast their Phase I Votes on the following wiki page:

Phase II Voting

More about this later.

Personal tools