Since version 1.5, a caching mechanism has appeared in Firefox that preserves the state of the page in memory. Caching is valid for one browser session. Navigating through the visited pages using the “Back / Forward” buttons, there is no need to download the page from the entire server. At the same time, the entire page, including js-scripts, is “preserved” in the state in which they were when the user left them. This mechanism allows you to navigate through the visited pages extremely quickly. The cache state remains unchanged while the browser session is in effect (until the user closes the bookmark, or the browser).
Not "bug", but "feature"
Among other things, the lack of understanding of this mechanism of browsers 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 run 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 most likely see that the spinner rotates, although in fact nothing happens.
The developer may consider that this behavior is nothing more than a browser bug or some of its features, and in search of a quick solution, mindlessly insert an extra handler to 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 instantaneous movement through the pages visited.
Working conditions
The page caching mechanism does not work if:
- the page defines handlers for unload and beforeunload events ;
- for page set ache-control: no-store;
- 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 listed in the past relative to the “Date” header (except when
- " Cache-Control: max-age = " is also specified)
- page not fully loaded;
- the page uses the IndexedDB transaction mechanism ;
- top level page contains frame, iframe (which, by the way, is never cached).
')
Events pageshow , pagehide
With the advent of BFCache, along with it, two new events have appeared. To get closer to them, consider the standard behavior of a web page:
- The user goes to the page.
- With loading of the page js-scripts are executed.
- As soon as the page is loaded, a load event occurs.
For some pages, there is a 4th step. If the page uses handlers for
unload ,
beforeunload , then these events are
raised 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), since In most cases, this work is not needed, and therefore the state of the page remains the same.
If you need the ability to run scripts every time a user is on the page, you should use the pageshow event.
Similarly, if you need to take action when the user leaves the page, you should use the pagehide event.
Event pageshow
This event is triggered just like the
load event, except that it is called every time the user hits the page (and the load event does not occur on the cached page). When a page is first loaded, the pageshow event occurs immediately after the
load event.
The pageshow event contains a
persisted boolean property that is
false when the page is first loaded. It is set to
true if the page has been cached by the browser (that is, if this is not the first page load).
Pagehide event
If it is necessary to define behavior for the moment when the user leaves the page, but there is no desire to use the
unload event (which will not allow the page to be cached), use the
pagehide event.
Like pageshow, pagehide contains a
persisted boolean 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 executes immediately after the
pagehide event.
Caching despite unload and beforeunload
If there is a situation when you need to use unload events, beforeunload, but at the same time retain the possibility of
BFCache , you can simply delete these events in their handler, and reassign them to 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 check 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 cachingWorking with BFCache