A time saving trick that’s messing with our data

Have you noticed a decrease in pageviews or unexplained increases in page load times since Chrome 96? Maybe you’ve spotted similar problems with Firefox and Safari users too. On the CRO side, you might have seen your A/B tests behaving strangely as you browse the site. Well we might be able to shed some light on a potential browser feature that may be causing these problems. Something that has been flying under the radar for a few years but is becoming more prevalent as browser compatibility improves.

Back/Forward, or bfcache, is a browser optimisation feature that allows instant navigation between a previous webpage using the browsers back and forward buttons, greatly improving a user’s browsing experience. Initially introduced as a Firefox and Safari feature, this is now available in Chrome for all users starting from version 96.

Essentially BF caching works by storing a snapshot of the page, preserving the javascript heap and DOM state when the user navigates away from the current page. When the user wants to return to the previous page using the back or forwards navigation buttons in the browser, the page is returned almost instantly from the browser in-memory instead of loading from another server request or disk cache.

How is this different to HTTP cache?

HTTP cache stores a response and reuses this on subsequent requests, which might sound pretty similar to what bfcache is supposed to do. However HTTP cache only stores responses of previously requested information, and very rarely can you load a full page from this alone. HTTP cache is also a disk-cache, which is faster than fetching from the network but is still slower compared to reading from a browser’s in-memory cache.

Why use Back/Forward caching?

The primary benefit of bfcache is speed. Users experience faster navigation to previously visited pages, making for a smoother, more enjoyable browsing experience. The effect of this feature can be a game-changer for those on slower connections or older devices.

What’s the catch?

One of the biggest issues we’ve encountered is that most analytics and testing tools don’t recognise bfcache restores as new pageviews. From an analytics standpoint, this is pretty crucial and can lead to underreported pageviews and misleading data about your site’s performance. It could even lead to slower average page load times. Load times from page loads that are replaced with bfcache restores most likely won’t be captured by your analytics tool. So despite the user experience actually being improved, the data would appear to show a decrease in performance.

From a CRO perspective, you’ll want to check that any changes or modifications to the page behave as expected in the cached page. Your traditional, static websites shouldn’t encounter too many problems as the JS heap is stored and your changes should persist as the page is returned from the cache. However, in the case where you have dynamic content or the site is re-rendering parts of the page after it has been returned from the cache, this might overwrite any changes you’ve made. Testing tools often execute on page load and code executed at this point won’t trigger again due to the page being restored from the cache.

However, there are workarounds and this can be accounted for using the page transition events, pageshow and pagehide.

The pageshow event will fire right after the load event when the page is initially loading, as well as any time the page is restored from bfcache. To identify cached page restores, the pageshow event has a persisted property which is true if the page was restored from bfcache, and false otherwise. You can use the persisted property to distinguish regular page loads from bfcache restores.

Below is an example of how you might want to trigger a pageview event after the page has been restored from cache:

To include bfcache restores in your pageview count, you will need to set listeners for the pageshow event and check the persisted property.

Conversely, the pagehide event fires either when a page unloads or when the browser tries to put it in the bfcache. This event also uses a persisted property to help identify whether it’s been cached or not, with a ‘false’ value meaning you can be confident the page isn’t going to enter the bfcache. However, when the persisted value is ‘true’, it doesn’t guarantee that a page will be cached. This purely means the browser intends to cache the page, but might fail due to other factors like those mentioned in the section below.

There are also some additional cases where this feature isn’t viable or won’t work as expected:

  • Unload events will cause problems across all common browsers and result in pages being classed as ineligible for bfcache. It’s recommended to avoid using the unload event and instead go for the pagehide event.
  • Embedded iframes are not eligible for the bfcache.
  • Most SPAs won’t benefit from bfcache as it works with browser-managed navigations.

BF caching is a fantastic feature that can significantly enhance user experience by speeding up site navigation and page load times. However, it is something that needs to be carefully considered from an implementation standpoint. This functionality needs to be accounted for using the relevant methods to ensure you’re capturing the most accurate data and, in terms of CRO testing, serving and maintaining a consistent user experience across your site.

References and useful articles:

https://web.dev/articles/bfcache

https://developer.chrome.com/docs/devtools/application/back-forward-cache

https://developer.chrome.com/docs/web-platform/deprecating-unload

https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching

https://nitropack.io/blog/post/back-forward-cache

https://www.smashingmagazine.com/2022/05/performance-game-changer-back-forward-cache/

Fancy a chat about Analytics & CRO?

Get in touch