Search code examples
javascriptbrowser-cachehttp-caching

API to check if a site has been served from browser cache


We would like to know from where the initial html document itself was served, either directly from the browser cache, our cdn cache or from origin. The later are easy (since our cdn adds server-timing to indicate a cache hit/miss), but figuring out if the document was served directly from the browser turned out more difficult.

I know about developer tools/network tab and how Chrome for example can show this information, but this question is specifically about any JavaScript API that can be used to detect and report it to us.

So far I've tried three things:

  • var isCached = performance.getEntriesByType("navigation")[0].transferSize === 0; from this answer, but today this seems to report the previous transferSize. When I try the same with the latest Chrome, I never get transferSize === 0, even when the devTools show me that it was cached. Possibly it only works for other resources, but not the html document itself.

  • var isCached = window.performance.navigation.type === 2 according to this answer gets the navigation type (in this case backward/forward), which is not always a true indicator of the document being cached. E.g. clicking a link is of type navigation and can also be cached.

  • Storing the timestamp in the document itself as suggested here on the server and comparing it does not work either, especially since we are using a cdn that has its own cache. We wouldn't be able to differentiate between a cached version from cdn or the browser.


Solution

  • From the MDN documentation and the PerformanceNavigationTiming interface described here, we can see that :

    the requestStart attribute returns the time immediately before the user agent starts requesting the current document from the server, or from the HTTP cache or from local resources

    We also have at our disposal the responseStart attribute :

    responseStart returns the time after the user agent receives the first byte of the response from the server, or from the HTTP cache or from local resources

    So, you should be able to detect when your initial HTML Document is served from the browser cache when the timing between the requestStart and responseStart is identical or almost identical.

    It will be something like the following:

    const timingDelta = 10; // to be conservative, but should be less than 5ms
    const performanceEntry = performance.getEntriesByName("<URL of your document>")[0]; // ex: performance.getEntriesByName("https://www.google.com/")[0];
    
    if (performanceEntry.responseStart - performanceEntry.requestStart < delta) {
        console.log('document was served from cache');
    }
    
    // that info is also available on the performance.timing object but it's deprecated
    // for your information, that would look like this:
    if (performance.timing.responseStart - performance.timing.resquestStart < delta) { ... }