By Sabir Valappil Thattath
Since the release of Enterprise Browser 1.5, I have been eager to write something about our cool new feature – Disk Caching. We have introduced disk caching functionality for webkit engines running on Windows Mobile/CE devices. This feature enables the browser to cache web resources locally on the device. This improves the page loading time and network bandwidth efficiency if user is trying to reload the same page.
Disk Caching Vs Memory Caching
Though Enterprise Browser supports memory caching, disk caching differs in its persistence behavior. In the case of memory caching, resources are stored in the application memory and will be lost once the instance is closed. Disk caching stores the resources into the physical memory (local file system) and makes them available even if you close and relaunch the Enterprise Browser application.
This enables faster loading of the pages if any pages were previously visited in the current or previous instance of the Enterprise Browser application.
As we are dealing with low-memory devices, there is always a concern about how much cache memory can be reserved for an application like Enterprise Browser. As we keep visiting pages, there is a good probability that memory cache can recycle its content once the upper cache limit is reached. When memory cache gets recycled, any previously visited pages look new to the browser, and it tries to fetch them from the server. This results in slower page loading and increased use of network bandwidth.
With Disk Cache in place, the browser first looks for the resource in the memory cache, and if not present, looks in the disk cache and finally to the server. As we have enough physical memory on the devices, we can overcome the recycling limitation of the memory caching feature.
It is very easy to enable disk caching. In Enterprise Browser app's config.xml file, look for the parameter:
Enterprise Browser stores the cached resources under a directory named "cache" that is located at the installed directory. This can be easily modified by the user by setting the config.xml parameter for the path:
<DiskCachePath VALUE="file://%INSTALLDIR%\EnterpriseBrowser\" />
We know that the resource gets cached after the first fetch from the server, and on further requests, EB fetches it from the cache. How long should this resource should be treated as fresh? There is a logic behind this too. And you might have guessed, it can be controlled by the server response HEADER. One can configure the freshness of each resource using following response header:
- Max-age (says how many seconds data should be treated as fresh by browser after caching)
- Expires (the date/time after which the resource is considered stale by browser after caching)
Enterprise Browser stores the resource in the cache along with the expiration information received during its last fetch from the server. Whenever a resource is requested, EB looks to see whether it is available in the cache, if yes it then checks for the freshness using the header values described above. If the data is fresh, the resource gets loaded from the local cache. Otherwise EB issues an If-Modified-Since request to the server for the required resource with time and date as "last cached date."
The If-Modified-Since request HTTP header makes the request conditional: the server will send back the requested resource, with a 200status, only if it has been last modified after the given date. If the request has not been modified since, the response will be a 304without any body. If server returns a 304, browser loads the resource from the cache. Otherwise it loads the newly received resource from the server and it caches the same.
What happens if someone didn’t configure the Max-age or Expires attributes in the HTTP header response. Will it cache the resource? It depends. EB has its own logic to treat a cached resource as fresh even if the user has not configured a max-age or Expires attribute. In this case, if there is a "Last-Modified" header present, the EB uses a heuristic to calculate a freshness lifetime for the response. Below is the config.xml parameter that is used in the absence of headers described above but in the presence of a Last-Modified header:
<DiskCacheExpTimeFactor VALUE="10" />
If Last-Modified time is "LMT" for a cached resource, and if the resource was cached at time "RCT," the resource is treated as fresh by the EB for a percentage of time RCT-LMT (by default EB set this to 10%).
DiskCacheTimeFactor = a percentage of RCT- LMT
In other words, at time (T), if EB needs a URL again and looks in the cache for it and has to use the DiskCacheTimeFactor, if T falls under the calculated DiskCacheTimeFactor time range, then the cached resource is used directly. Otherwise a conditional GET (If-Modified-Since) is used to determine whether or not the previous response may be reused.
Setting the DiskCacheTimeFactor to zero will cause the resource to be fetched from the server every time it's requested.
I could see around 50-60% improvement with EB1.5 in a scenario where page was cached in the previous instance.
Sabir Valappil Thattath is a Senior Software Engineer with Zebra Technologies