Thursday, April 16, 2015

How to manage browser cache on SapUI5 / OpenUI5 applications - CacheBuster

The problem: you have an SapUI5 / OpenUI5 application currently being used and you want to change something to it. How do you force users to start loading the latest version?

Webapps are comprised of objects loaded via HTTP. These objects are mostly, images, html, javascript or css files. All these files are served with a validity date that can be set on the server. Browsers, for performance reasons, only load an url if they don't already have a copy of that resource in their cache or if the copy's validity already expired.

On *UI5 apps we cannot easily set the validity of the objects loaded server side so the only way to force users to load a new version is to force a change on the url being requested. This can be done by appending a parameter, changing the name of the object (view/controller, etc.) or, using the CacheBuster feature on UI5 that does this automatically.

When using CacheBuster, everything that is loaded via the jQuery.sap.require function has a timestamp inserted in the middle of the url. Because this timestamp can be controlled by developers, they can force browsers to load the latest version of the urls.

So, instead of the browser making this example request:
https://<hostname>/sap/bc/ui5_ui5/sap/<projname>/<appname>/main.view.js
It does the following:
https://<hostname>/sap/bc/ui5_ui5/sap/<projname>/~20141018120538~/<appname>/main.view.js

 This timestamp makes the url unique and it theoretically contains the timestamp this object was last changed. When the application is first started, the framework does a request to an url to get a json that tells it the timestamps when each file was last modified. These timestamps are then automatically appended to all requests.
This url to this json is something like :
https://<hostname>/sap/bc/ui5_ui5/sap/<projname>/sap-ui-cachebuster-info.json

 How to enable cachebuster on your ui5 app?
Too easy, just append data-sap-ui-appCacheBuster="./" to the script tag that loads the ui5.
e.g.

 <!DOCTYPE HTML>
<html>
 <head>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
  <script src="resources/sap-ui-core.js"
    id="sap-ui-bootstrap"
    data-sap-ui-libs="sap.ui.commons"
    data-sap-ui-theme="sap_goldreflection"
    data-sap-ui-appCacheBuster="./">
  </script>



Now, whenever you change the project or transport a new version, execute report /UI5/RESET_CACHEBUSTER on the backend. This report resets all these timestamps. I do not know if they are supposed to be reset automatically when checking in a new version or when transporting, but from my experience, manually executing is the only reliable way.

 Hope it helps

4 comments:

  1. Hi. Thanks for sharing this information. I tried it with one application and observed, that e.g. view.xml and view controller are loaded from the cache buster but not those modules, which are loaded by using 'jQuery.sap.require'. Any ideas?

    ReplyDelete
  2. Not sure I understand. Which modules?

    ReplyDelete
  3. Thanks Tiago for prompt reply. Those are own modules in customer name space (like JS files) I have placed in sub directories.

    ReplyDelete