Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect application version change on a single page application

today a question was raised here and I don't have an evident answer.

Assume that we concatenate and minify all resource files (CSS and Javascript) and declare them in the "Master-Page".

On a multi-page app, if a CSS file changes it will be recharged on the next full page load.

On a single-page app, the user can keep working for days and never recharge the main page where the CSS files are declared. The user will never see the changes until a Ctrl-F5 is issued.

I'm sure someone already thought of this and have an experience to share :)

For me, using WebSockets is not an option. First because it's overkill and second because not all my clients support the technology. Same reason applies to all WebSockets fallbacks... I won't keep hitting my servers because of this.

So, any ideas anyone? :)

BTW, we're using AngularJS if that can help for a specific solution.

Thanks!

like image 204
AlexCode Avatar asked Apr 14 '14 09:04

AlexCode


People also ask

What is SPA framework?

An SPA (Single-page application) is a web app implementation that loads only a single web document, and then updates the body content of that single document via JavaScript APIs such as XMLHttpRequest and Fetch when different content is to be shown.

What are the features of a single-page application?

What is a single-page application? A single-page application is a web app that consists of a single HTML page, loads new JSON data from the server, and rewrites the page in response to user actions. Unlike MPAs, SPAs don't need to load each new web page from scratch — they simply alter the existing page.

How do I force refresh react app?

If set to true, the browser will do a complete page refresh from the server and not from the cached version of the page. import React from 'react'; function App() { function refreshPage() { window. location. reload(false); } return ( <div> <button onClick={refreshPage}>Click to reload!


2 Answers

I've getting through this same problem. My solution which is opiniated and may not respond to your criterias :

When i package my front-app and my server-app, I share a configuration file containing the current version of the front-app.

Front side : 75% of my routes change implicitely call a Webservice (route change resolve). SO each time I call my server I include a custom HTTP header (or a GET/POST param) containing the client version of the front-app.

Server side : I compare the front-app version (the one in the browser of the user, loaded last time user refreshed/loaded the SPA) with the front-app version of the shared configuration file :

  • If version matches : I Do nothing.
  • If version don't match I send a custom HTTP status error code (418 for example)

Then front side: I added a response Interceptor that intercepts any 418 error code and do a force-refresh of the whole app

That's it. Basically the event that "check" if the front-app version is the latest is a route change (that calls a WS via ajax). But you could add some infinite $interval calling a dedicated WS each 5 minutes or so... I can add some code if needed.

Hope this helps ;)

like image 173
Jscti Avatar answered Oct 06 '22 00:10

Jscti


Assuming that you are using AngularJS' routing via $route service and provider, then you can use $routeChangeSuccess event to perform a server request if there are significant changes that needs to be changed; if there are any then you can do a window.location.reload() to refresh the page and get all the updated resources and htmls.

The following process can be changed depending on how you want to implement it:

1. Setup a config file in your server indicating the app's version. You may also choose to assign different versions for different files but since you have concatenated all your resource files then I guess you may limit your version options in your configuration.

2. Create a service that contains all the necessary information(versions of files from the server) and methods to perform a server request to your server to check against the current file versions stored in the service.

3. Use $routeChangeSuccess event to perform a server request using the service that you have created in step 2, if the request returned a valid confirmation that there were changes then do the force page reload via window.location.reload().

like image 39
ryeballar Avatar answered Oct 05 '22 23:10

ryeballar