Ajax Toolkit Caching
Ajax Toolkit Caching
Reliable caching of ajax toolkits in a cross-domain fashion will significantly improve Ajax web application performance.
Why Is This Important?
- Most of the Ajax enabled web applications using some kind of Ajax toolkit;
- A typical Ajax toolkit has a download footprint of 50KB to a few hundred or even higher kilobytes;
- 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;
- Cross-domain caching of selected few leading Ajax toolkits will likely improve performance of thousands of Ajax enabled websites immediately;
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
- 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." http://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html Basically, if there's a cache, it'll have to be cryptographically signed.
(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.
.jar files have done for Java or
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.
- 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
- 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
- Allow <link> tags to reference compressed archives on the server
- Default option is to load immediately and synchronously so that all references will be available when needed
- Optionally, the archive may be loaded asynchronously in a background thread
- Optionally, the archive may be loaded asynchronously after the body's
onLoadevent has been triggered ("deferred")
- Substitute archived content for matching external resources referenced in other tags such as anchors, script sources, images, iframes, objects and perhaps even
- Determine the URI of the archived resource either by:
- ...concatenating the base URI of the archive to the relative path of the resource within the archive
- ...assuming all bundled resources are semi-absolute though protocol, server and port agnostic
- (one of the two methods above would need to be standardized upon, or an option to choose should be provided)
- (optional URL parameters should be ignored for matching, but provided to the script runtime as they are now)
- Determine the URI of the archived resource either by:
- Provide options to page designers for handling background loads of archives
- 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
- Provide an option to always load a specific resource from the server, regardless of archive content
- Provide an option to load immediately if no currently consumed archive contains the content for that reference (a "high priority" option)
- Provide an option to associate specific resources to an archive, perhaps by connecting resource-dependent tags to the archive <link> through the link's
idattribute; 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
- If an external resource is not found in any archive, it will be loaded and cached from the server as usual
- Provide options to control time stamp comparison/refresh logic
- Provide a "priority" option to the <link> tag to control refresh logic for all resources within that archive
- 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
- 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:
The archive has content:
/dojois a directory
- Other files and directories exist as siblings to
/dojo/dojo.jsand subordinate to it
/dijit/...hierarchy also exists
/dojox/...hierarchy also exists
/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>
relattribute type of "Archive"
- The optional
archiveattribute on the <script> tag (could also have been
- The obviously non-standard
djConfigattribute on the <script> tag, which is part of the Dojo Toolkit paradigm
archive attribute could alternatively work like a
src attribute, using fragment notation to indicate the <link> identifier...
...or provide convenient association to an archive without a <link> tag:
(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
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.