Technical Articles
Cache Buster Indexing UI5 Tooling Task
Introduction
I think today almost everyone is aware of the cache buster mechanism in UI5. In case you never heard about it or you have no clue what it does, it’s explained very well by SAP here
https://ui5.sap.com/#/topic/91f080966f4d1014b6dd926db0e91070
The cache buster mechanism enables UI5 applications to benefit from browser caching and still makes sure the browser bypasses the cache when a new version of the app is available.
Or how it’s explained in the documentation:
A cache buster allows SAPUI5 to notify the browser to refresh the resources only when the SAPUI5 resources have been changed. As long as they are not changed, the resources can always be fetched from the browser’s cache. |
This cache buster concept adds a timestamp to the path of each file like “~20120716-0201~”. This allows the cache buster to update this file in the cache by changing the timestamp to access the file. For generating these timestamps and provide the paths, SAP has cache busting indexing mechanisms for Java, ABAP and embedded into BTP. But not for HANA XS or on any other system for serving OpenUI5 apps:
When you search for Cache Buster solutions on HANA XS and XSA, you might find some already.
In this blog I want to provide another solution to do this making use of the UI5 Tooling.
Enable Cachebuster in the app
Before explaining the solution, let’s enable cache buster in your OpenUI5 app. This needs to be activated in the bootstrap code in the index.html page like this.
<script
id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-cachebuster/sap-ui-core.js"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-resourceroots='{"be.wl.cachebusterdemoapp": "./"}'
data-sap-ui-compatVersion="edge"
data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
data-sap-ui-async="true"
data-sap-ui-preload="async"
data-sap-ui-frameOptions="trusted"
data-sap-ui-appCacheBuster="./"
></script>
Maybe you don’t see the differences immediately so let’s focus on the parts that differs from the default bootstrap code.
First part is the “src” property, here we add “sap-ui-cachebuster” between “resources” and “sap-ui-core.js”:
src=https://openui5.hana.ondemand.com/resources/sap-ui-cachebuster/sap-ui-core.js
Second, the property “data-sap-ui-appCacheBuster=”./”” needs to be added to the bootstrap like this:
data-sap-ui-appCacheBuster=”./”
Test the App with CacheBuster locally
The CacheBuster mechanism can be tested locally by building the app with the task “generateCachebusterInfo” and run it from the “dist” folder.
“ui5 build -a –clean-dest –include-task=generateCachebusterInfo” |
Let’s Install “serve” to test the dist folder locally
npm i –save-dev serve
Add a start dist script to Package.json
“start:dist”:”serve dist”,
Run it:
npm run start:dist
Problem
Running the app from the dist folder will not work. With CacheBuster enabled, UI5 is adding the generated timestamp from the CacheBuster info file to the request url. This path does not exist in the “dist” folder.
This would be the exact same problem on an XSA server or none Fiori Launchpad environment. In other system you could solve this with a Java Servlet or PHP script. In the next step I will provide you an alternative.
Solution
As a solution for this problem, I created a Cachebuster indexing task for the UI5 tooling. This task will generate the CacheBuster info page, which contains all the files and their timestamp for the CacheBuster mechanism and use this CacheBuster info file to copy each file of the UI5 project to a folder with the generated timestamp. This will make sure that all request paths including timestamps generated by the CacheBuster mechanism can be resolved.
The UI5 tooling task is available on NPM:
https://www.npmjs.com/package/ui5-task-cachebuster-indexing
This makes it easy to consume, simply install the npm package:
npm install ui5-task-cachebuster-indexing –save-dev
Add as a UI5 dependency in the package.json
"ui5": {
"dependencies": [
"ui5-task-cachebuster-indexing"
]
}
Make sure it run behinds the last possible step (eg generateVersionInfo) or after generateCachebusterInfo. The task generateCachebusterInfo is not required as this is included in this Cache Buster Indexing task as well.
Define the task ui5.yaml config as a custom builder task:
builder:
customTasks:
- name: ui5-task-cachebuster-indexing
afterTask: generateCachebusterInfo
Build the app and you’ll see your productive app in the dist folder with a copy of each file in a folder with the related timestamp. The dist folder isn’t that beautiful anymore but it should only provide you a productive app. It doesn’t matter much what’s in it as long as it does the job 😊
Run test from dist folder again
Known limitations
The task “generateCacheBusterInfo” from the UI5 Tooling can be configured to work with hashes or timestamps. Like in this example: https://sap.github.io/ui5-tooling/pages/Configuration/#cachebuster
Currently this configuration is not taken into account in the custom task for Cache Buster Indexing. It’s not yet possible, or at least not that I know of, to access global config in a custom task.
Resources
This UI5 Tooling task is available on npm: https://www.npmjs.com/package/ui5-task-cachebuster-indexing
You can find the code of this package on GitHub: https://github.com/lemaiwo/ui5-task-cachebuster-indexing
The demo project is also available on GitHub: https://github.com/lemaiwo/cachebuster-demo-app
It is also listed in the UI5 Tooling Ecosystem Showcase: https://ui5-community.github.io/ui5-ecosystem-showcase/
Hope this will help you with any caching problems in your OpenUI5 project! 😉
Hello Wouter,
Thanks for sharing this blog post. I was trying with this tooling to enabling my ui5 app for cache buster set up. But I have encountered a few issues here.
The build worked as per your blog post. But I need to deploy my code back to ABAP server. So when I tried that it failed because it is now having folders which starts with '~' sign and that is not being accepted.
Also I find all my files are duplicated under dist folder, and artefact count doubled kind of. So I had to drop off this approach and tried with an old method by using script tag in my index.html file as below.
Now by doing this it gets attached some hard coded version at the end of the file ( being picked up from verison.json file) while getting loaded and it serves my purpose, only problem is one of the file (a controller under webapp folder) is NOT being considered while adding the version tag at the end of the file, hence its always disk cached.
So could you please share some thoughts how to fix this issue, and also at the same time, I felt may be I am not doing the tooling part properly or may be this npm plugin is not built for ABAP deployment (my guess only).
If you please share your views on that. Thanks in advance!
- Regards , Somnath
Hi Somnath,
Thank you for your interest in this topic. Normally (depending on the version of your backend) this is not needed if you are working on an ABAP system with the gateway component. It has cachebusting mechanism already in the system but you have to run the report "/UI5/APP_INDEX_CALCULATE".
The purpose of this UI5 Tooling extension is rather for standalone UI5 applications on HANA XSA system or a OpenUI5 app on any other webhost.
I also tried the solution you proposed but somehow this made the performance of the app very slow...
Kr, Wouter
Hi Wouter,
P.S. I belief the URL in your introduction should point to the AppCacheBuster page? https://ui5.sap.com/#/topic/ff7aceda0bd24039beb9bca8e882825d
Best regards,
Pieter
Hi Pieter,
It doesn't matter where you develop your app. Cache buster is working inside the launchpad service of BTP.
The Launchpad service works together with the html5 app repo service so yes it supports this.
Regarding docu, not much available on this except it is mentioned here: https://help.sap.com/viewer/ad4b9f0b14b0458cad9bd27bf435637d/Cloud/en-US/7adacc5987b34a2d89655aebfdbb2a66.html?q=cache
Kr, Wouter
Hi Wouter,
What is your use case for serving dist locally?
It's sufficient to use a proxy/middleware to link the path including the cache timestamp to the actual resource. This is most probably also what is done by the HTML5 Repository Service.
To use app cache busting in a deployed @sap/approuter app I have also solved this by providing a generic route for these cache buster paths.
Best regards,
Pieter
In my case the app is running on hana xsa with not all cf services available, no html5 app repo and launchpad service.
Normally the launchpad service handles cache busting.
Why dist folder? Webapp should be for development purposes or debugging. Dist for productive usage. Cache busting is only needed for end users and not a problem while developing.