Last year, I wrote about the IE9 improvements in heuristic expiration, which apply when a server fails to specify how long a cached resource should be treated as fresh. Heuristic Expiration works by calculating an implicit freshness lifetime from the Last-Modified timestamp on the cached resource and the timestamp at which the resource was downloaded from the server.
However, the Heuristic Expiration calculation only applies when the user’s Check for newer versions of stored pages option (a.k.a. “SyncMode“) inside Tools > Internet Options > Browsing History Settings is set to Automatically.
As mentioned, the heuristic expiration feature relies upon the server providing a Last-Modified timestamp on the response. If the server fails to provide such a timestamp, then Internet Explorer will fall back to its Once-Per-Session syncmode for that resource. A user may elect to use Once-Per-Session syncmode (for all resources) in lieu of Heuristic Expiration by selecting the Every time I start Internet Explorer radio button.
WinINET keeps track of when the current process has started in a variable called SessionStartTime. Every entry in the WinINET cache has a LastSyncTime. If the cache syncmode is Once-Per-Session, when WinINET is deciding whether or not to reuse a resource of unknown freshness, it compares the resource’s LastSyncTime to the process’ SessionStartTime. If the LastSyncTime is earlier than the SessionStartTime, WinINET will not immediately reuse the cached version and will instead make a network request to the server to check for freshness, potentially downloading an updated version of the resource in the process.
Once-Per-Session syncmode has a few non-obvious subtleties.
- To establish an upper-bound on reuse, WinINET will also perform revalidation if the current time is more than 12 hours after the LastSyncTime.
- If INTERNET_FLAG_HYPERLINK is present on the request, and a cached response doesn’t have a Last-Modified value set, then WinINET will always revalidate the cached resource before reuse, ignoring the Once-Per-Session rule. IE9 uses FLAG_HYPERLINK (via BINDF_HYPERLINK) when performing most document (e.g. top-level or frame) downloads.
- In Internet Explorer 8, simply opening a new tab (which creates a LCIE Tab process) would reset the SessionStartTime for all other tabs in the current Browser Session. This behavior hurt performance, and was corrected in IE9. In IE9, every new tab process in a Browser Session will inherit the original SessionStartTime for the browser session, eliminating this performance penalty.
So, what does this gobbledygook all mean to you, the web developer? Avoid the confusion and unpredictability of cache heuristics and specify an explicit expiration time!