Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save adrienv1520/7e4bacc44849b7daa5ce323bcc800272 to your computer and use it in GitHub Desktop.
Save adrienv1520/7e4bacc44849b7daa5ce323bcc800272 to your computer and use it in GitHub Desktop.
How to force a page to reload from server at browser launch with JavaScript

How to force a page to reload from server at browser launch with JavaScript

I spent weeks finding a way to refresh a page or a tab from the server once a user starts or restarts the browser. I was very surprised to find nothing about this topic.

Let's dig into the context, tries and the solution I came up with.

Context

Typically, once a user opens a browser and gets to a page, it directly provides the page in cache without refreshing any data from the server. Obviously, this only applies if the user is not in a private navigation.

In this case, as a user, I always need to open the browser and then manually reload the page to get the last updated data. What? Am I too lazy? Sure I am a developer!

My goal was to detect when the browser launches and automatically refresh the page or the tab at this moment so end users do not need to manually reload the page and updated data immediately come to their eyes! Sounds nice!

Tries

As I am using a Service Worker that in my case handles expired pages and refreshing data (requesting data from the server if a page expired), I noticed the navigation through the browser was always in a back forward state when loading the page after browser launch and actually bypassed the Service Worker to return the page from cache. No way!

Here are the solutions I tried:

  • set Cache-Control header to no-cache, max-age=0, must-revalidate for all my pseudo-dynamic pages so it will force the browser to automatically refresh them. My Service Worker was in charge to set this header so my assets still were cached in my CDN. It was okay because my Service Worker was handling these pages based on an expiration date so they still were put in cache based on this date. But it did not work, once the browser launched and and I accessed the page, it still was outdated data loaded from cache;
  • detect when a tab becomes active to reload the page using tabs API but I found nothing really useful;
  • use localStorage API in combination with page Visibility API to store when users first loaded the page, detect when they left the page and reload it when the page becomes visible after a certain minimum amount of time (saying 10 minutes for an example). No way to make it worked at browser launch, it only automatically refreshed the page when the user was getting back to the tab passing 10 minutes (not so bad, but was not my use case).

I still was unable to detect browser launch in my JavaScript.

The solution

I finally came up with a solution using Performance and PerformanceNavigationTiming Level 2 APIs.

Experimental

PerformanceNavigationTiming Level 2 API is still at a Working Draft status which means this solution is using an experimental technology. Please use with caution.

Browser compatibility

Browser compatibility is not as bad as expected for an experimental feature. Only Safari, iOS Safari and IE are not supported the solution.

API Chrome Edge Firefox IE Opera Safari WebView Android Chrome Android Firefox Android Opera Android iOS Safari Samsung Internet
Performance 6 12 7 9 15 8 <=37 18 7 14 9 1.0
Performance.getEntriesByType 28 12 35 10 15 11 <=37 28 35 15 11 1.5
PerformanceNavigationTiming 57 12 58 No 44 No 57 57 58 43 No 7.0
PerformanceNavigationTiming.type 57 12 58 No 44 No 57 57 58 43 No 7.0
PerformanceNavigationTiming.unloadEventStart 57 12 58 No 44 No 57 57 58 43 No 7.0

Code

if ('performance' in window) {
  const navigationLastEntry = performance.getEntriesByType('navigation').pop();

  if (navigationLastEntry
      && navigationLastEntry.type === 'back_forward'
      && navigationLastEntry.unloadEventStart === 0) {
    window.location.reload(true);
  }
}

Usage

This code does not need the DOM or the page to be loaded to be used. Actually it should be executed before these events are fired.

I typically put this code at the first lines of my index.js file, outside DOMContentLoaded event, but you could use it in the head section of your document. Personally speaking, it reloads really fast the page even though used in the index.js referenced at the end of my HTML files. Adapt to your need.

How it works

First the code checks Performance API is supported by the browser.

It then get the last navigation entry.

Finally it will reload the page only if:

  • there is a last navigation entry;
  • the type of navigation is back_forward;
  • the time immediately before the user agent starts the unload event of the previous document (unloadEventStart) equals 0 which means there is no previous document.

Please note that the navigation is through the browser's history traversal operation back_forward when:

  • users press Previous/Next buttons in the browser;
  • users press Previous/Next buttons on their keyboard;
  • users start or restart the browser and get to the page or tab.

These 3 conditions all put together allow us to detect when the browser loads the page or tab after and only after the browser has launched. Any other back_forward navigations won’t make the page to reload.

Finally calling window.location.reload() with true option indicates the page will reload from the server, false or no argument to reload from cache.

That’s it! At the end of the day that was a quite simple solution!

Discussion and Contribution

As I am more of a back-end developer, please let me know if something's wrong or feel free to contribute if you have an alternative or better solution.



Thanks,
Adrien
@onkihara
Copy link

Thank you very much, Adrien! This was exactly what I was searching for - great solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment