Problems with Application Cache

This blog lists the difficulties and drawbacks faced when using the Application Cache. Solutions to most of these issues are described in another article called Tips for using Application Cache?

  • Double Refresh Issue - This is perhaps the biggest problem with manifest files. If the content for the page has been updated, the user will view the old content that was in the Application Cache until it has been updated. However, the Application Cache is not updated until the user views the page, as shown in the diagram below. This ultimately means that when the manifest file is updated (triggering the Application Cache to be updated) the user will not see the new content until they view the page for the second time. After content has been updated, the first time a user views the page they will view the old content loaded from the Application Cache. In the background the Application Cache will be updated and will receive the updated content. The second time a user views the page they will see the updated content.  This is particularly problematic if not all the page resources are in the Application Cache. For example if a manifest file is "open" (as it has a * in the NETWORK section), any resource not listed in the CACHE (or FALLBACK) section will not be stored in the Application Cache. These resources will be downloaded freshly every time the page is viewed (however normal caching rules apply for Browser Cache, Proxy Caches, etc). The user may, therefore, get fresh copies of any resources not listed in the manifest file and stale copies of those resources listed in the manifest file until they refresh the page for a second time.
  • Atomic - Once a file is cached, the browser will continue to show the cached version, even if you change the file on the server. If you want to update a single file in the Application Cache, all files must be updated at the same time. Any change made to the manifest file will cause the entire set of files to be downloaded again.
  • Asynchronous - If a manifest file is added to a HTML file, it forces all resources to be downloaded synchronously as soon as the manifest file is downloaded. Therefore resources that may not yet be required, such as JavaScript or an image below the fold, will be downloaded at the start of the page. This means it is harder to control the order that resources are downloaded. This is particularly problematic for sites that want to download JavaScript asynchronously to ensure that JavaScript does not impact the downloading of visible page elements. In addition if a site developer wanted to delay the download of images that are not initially visible, it would not be possible to add these to the manifest file. If they were added to the manifest file they would be downloaded at the start of the page as soon as the manifest file was downloaded. The best way to reduce this problem is to be careful about the order of files listed in the manifest file.
  • Forces HTML to be Cached - Adding the manifest file to a HTML page adds the HTML to the Application Cache. If your HTML is dynamic but your css, images and JavaScript are static (or fairly static) it is not possible to use the Application Cache by adding it to your HTML page. There is a way around this limitation as described in my next blog article Tips for using Application Cache?
  • Unreliable JavaScript API - The JavaScript API for the Application Cache described in my previous blog, can be unreliable. For example often the window.applicationCache.onupdateready eventhandler doesn't get called on iPhones and Androids. This may be exacerbated because some devices cache the manifest file even when it is marked as Cache-Control: max-age=0. If the manifest file is cached then updating the manifest file on the server will not cause the Application Cache to be reloaded as the browser will receive a copy of the cached manifest file prior to the update. It is important to avoid caching the manifest file by ensuring the web server serves the manifest file with Cache-Control: no-store, no-cache and Expires: 0.
  • Internet Explorer 10 - According to Matt Andrews
    "IE10 will reject any manifest file that has the headers suggested above Cache-Control: no-store, no-cache and Expires: 0 and the web app won’t work offline. We worked around this by setting the expiry to 1 second (but only for IE10). As we use JavaScript to inject an iframe containing the manifest file (as you described in one of your other posts to avoid caching dynamic HTML) we can use a quick bit of user agent sniffing to load the manifest with a different query string to other devices that identifies it as IE10. We also add no-transform to Cache-Control so we stop the mobile networks from caching or mangling the manifest file on our behalf."