Back / Forward Cache - a mechanism for caching pages in a browser

Starting with version 1.5, a caching mechanism has appeared in Firefox that saves the state of the page in memory. Caching is valid for one browser session. Moving through the pages visited using the "Back / Forward" buttons, there is no need to download the whole page from the server. At the same time, the entire page, including js-scripts, as it were, is “preserved” in the state in which they were when the user left them. This mechanism allows you to navigate the pages visited extremely quickly. The cache status remains unchanged until the browser session is active (until the user closes the bookmark, or browser).

Not a “bug”, but a “feature”

Among other things, a misunderstanding of this browser mechanism causes a real headache for developers. Consider an example.
There is a form whose data we want to send to the server. We want to somehow visualize this process and start the spinner when submitting the form. The browser goes to the next page. If we go back using the browser's back button (or through window.history.back () ), we will most likely see that the spinner is spinning, although nothing actually happens.

The developer can consider that this behavior is nothing more than a browser bug or some of its features, and in search of a quick solution, thoughtlessly insert an extra handler on the unload event (the first item in the list below). Thus, the developer refuses BFCache in general, thereby depriving its users of the possibility of almost instantly navigating through the visited pages.

Working conditions

The page caching mechanism does not work if:
  • the page defines handlers for unload , beforeunload events ;
  • the page has cache-control: no-store installed ;
  • the site is under HTTPS and at least one of the following rules is set for the page:
    • Cache-control: no-cache
    • Pragma: no-cache
    • Expires: 0 or “Expires” is indicated in the past relative to the “Date” header (except when
    • " Cache-Control: max-age = " is also specified)
  • the page has not fully loaded;
  • The page uses the transaction mechanism IndexedDB ;
  • the top-level page contains frame, iframe (which, by the way, are never cached).


Events pageshow , pagehide

With the advent of BFCache, two new events appeared with it. To get closer to them, consider the standard behavior of a web page:
  1. The user goes to the page.
  2. With page loading, js scripts are executed.
  3. Once the page has loaded, the load event is raised .

There are 4 steps for some pages. If the page uses handlers for unload , beforeunload , then these events are triggered by the browser when the user leaves the page. In this case, the page is not cached.

When the user returns to the cached page, the scripts are not executed again, and the load event also does not occur (steps 2,3), because in most cases, this work is not needed, and therefore the page state remains the same.

If you need the ability to execute scripts every time the user is on the page, use the pageshow event.
Similarly, if you need to take action when the user leaves the page, you should use the pagehide event.

Pageshow event

This event fires just like the load event , except that it is fired every time the user lands on the page (and the load event does not occur on the cached page). When the page loads for the first time, the pageshow event occurs immediately after the load event .

The pageshow event contains the boolean persisted property , which is false when the page first loads. It is set to true if the page is cached by the browser (i.e. if this is not the first page load).

Pagehide event

If you need to determine the behavior for the moment when the user leaves the page, but there is no desire to use the unload event (which will prevent the page from caching), use the pagehide event .

Like pageshow, pagehide has a boolean persisted property . Similarly, it is false if the page is not cached, and true otherwise.
If this property is set to false , then the unload handler runs immediately after the pagehide event .

Caching despite unload and beforeunload

If a situation arises when you need to use the unload, beforeunload events, but at the same time retain the ability of BFCache , you can simply delete these events in their handler and reassign them in the pageshow event handler:

window.addEventListener('pageshow', PageShowHandler, false);
window.addEventListener('unload', UnloadHandler, false);
function PageShowHandler() {
    window.addEventListener('unload', UnloadHandler, false);
}
function UnloadHandler() {
    window.removeEventListener('unload', UnloadHandler, false);
}


Cross-platform

The BFCache mechanism appeared in Firefox 1.5, and has long been actively supported by all modern browsers. To test browser support, you can use the following approach:

if ('onpagehide' in window) {
    window.addEventListener('pagehide', exitFunction, false);
} else {
    window.addEventListener('unload', exitFunction, false);
}


Related Links

Using Firefox 1.5 caching
Working with BFCache

Also popular now: