Technical Articles
UI5 Tips: Adding a Splash-Screen / Loading indicator
UI5 apps always take a little time to load. If you don’t take any precautions, the user will be looking at a blank screen while the app is loading.
It is fairly simple to add a splash screen and loading indicator to improve the user experience. This will give your app a more professional appearance, and it will cost minimal effort.
This post shows you exactly how to do this. You might also be interested in checking out the sample app from github so you can run it yourself.
Running the app
The loadingscreen sample app is in the loadingscreen subdirectory of this repository. Simply expose the folder and all its contents with a webserver, and navigate to its index.html
How does it work?
In various tutorials and the ui5 walkthrough, the <body>
is usually left empty. This is for a good reason – any content that is in the body would simply show up on the page, as is shown in the walkthrough’s “Hello world!” example. But there is an exception: if an element has an id
attribute with the value busyIndicator
, then this content will be hidden after the ui5 bootstrap code is finished and the app content is placed inside the body.
In the loadingscreen sample, the index.html page has a static <div>
element with an id
attribute with the value busyIndicator
as static content in the <body>
element. Indside that <div>
we can place anything we like. In the example, the div contains a header and a footer with static text to indicate that the application is loading. Between the header and the footer is an image of the ui5 logo, and a css animation, which superficially resembles the ui5 busy indicator animation:
<body class="sapUiBody" id="content"> <!-- Loading splash screen --> <div id="busyIndicator" style="text-align: center; font-family: Sans, Arial"> <!-- static header text --> <h3>My UI5 App is loading</h3> <!-- static image of the ui5logo --> <img src="images/openui5-logo.png" class="logo"/> <!-- loader animation CC0 licensed code used with permission from https://loading.io/css/ --> <div class="lds-ellipsis"> <div></div> <div></div> <div></div> <div></div> </div> <!-- end of loader animation --> <!-- static footer text --> <center><h5>This may take a few moments...</h5></center> </div> </body>
The css animation requires some css, and this is included simply as a static css resource by including an appropriate <link>
element in the <head>
of the page:
<head> <!-- css required for the loading screen css anumation --> <link id="animation" rel="stylesheet" type="text/css" href="css/progress-animation.css"/> </head>
In this case, we pulled the css animation from the excellent site https://loading.io/css/, which provides many different free css animations.
Note that any css required by the loading screen must really be included statically via the <link>
or <style>
element. The standard ui5 mechanism to include css by declaring it in the manifest.json is no good as it will be loaded as part of the ui5 bootstrap, and the whole idea of the loading screen is to show something before the ui5 bootstrap even starts.
What does it look like
This is what it looks like when the app is loading:
The text, logo image, and the loader animation are all static content and will show during UI5 bootstrap.
Next Steps
Obviously, this loading screen is only an example to show how you can make it work. The entire design of the loading screen is up to you.
Just remember to keep it light and quick: the whole reason to include a loading screen in the first place was to give the user something to look at while ui5 is bootstrapping. If the loading screen itself requires a lot of resources then it defeats its purpose. For this reason, you might consider including
any css directly using the <style>
element, rather than relying on a network request to load external css with the <link>
element.
Finally
Did you like this tip? Do you have a better tip? Feel free to post a comment and share your approach to the same or similar problem.
Want more tips? Find other posts with the ui5tips tag!
Great idea Roland - this should work great on standalone UI5 apps. In the event an app is accessed via the Portal/Launchpad service, do you have any ideas on how to do something similar?
Hi Matthew!
thanks for chiming in - this is a great point! I mostly have developed apps for hana and a few standalone - not for the launchpad.
If you have the time, could you please post an issue in our github repo? This allows me to track this and investigate:
https://github.com/just-bi/ui5tips/issues
Thanks in advance!
Roland
Where can we find more info on this? This does not work out of the box on OpenUI5 V1.84
Hi Dimitar,
does it work for you with the sample app?
https://github.com/just-bi/ui5tips/tree/main/loadingscreen
Thanks for the response Roland,
It does work when I run the sample.
I compared the index.html files and found some differences - on my project the body looks like this:
More precisely: there is no inner div tag with the id of 'content'. When I removed this id from the index.html of the sample project the splash there also ceased working.
The question now is why does this play a role and what is the 'right' body structure for the index.html file.
Thank you for your helpful post.
Hey, that is an interesting observation!
in your initial comment, you asked where we could learn more about this, and the reason I didn't answer to that directly is that I just don't know. At some point I simply observed the behavior, and I have been (ab)using it ever since. Prior to that, I used a different technique, where I would use plain DOM to do content substitution and hiding, and that works too, but obviously the technique proposed in the sample is much simpler, which is why I wrote about that.
If you happen to find out more, feel free to post your finding.
Cheers and good luck,
Roland.
Hey Roland,
I think the reason for this, you can find here: https://github.com/SAP/openui5/blob/097469704f7c00e5d2c138d8a2001c97ccbc72a4/src/sap.ui.core/src/sap/ui/core/RenderManager.js#L2190
more specifically here in this line: https://github.com/SAP/openui5/blob/097469704f7c00e5d2c138d8a2001c97ccbc72a4/src/sap.ui.core/src/sap/ui/core/RenderManager.js#L2266
apparently it does not matter at all what the value within your `id` attribute is. I tested it by just using the value 'test', all it cares about is whether or not a node has an `id` attribute set in the first place and will therefore be preserved (and later on, because it is preserved set to be forced hidden, see: https://github.com/SAP/openui5/blob/097469704f7c00e5d2c138d8a2001c97ccbc72a4/src/sap.ui.core/src/sap/ui/core/RenderManager.js#L2119) during rendering of the root.
Great blog post! It was the reason for me to look into this in the first place! 🙂
BR
Marco
Hi Marco,
Thanks for the kind words, and thank you so much for the insights! Much obliged.
Thank you for the nice blog.
I would have a question: what about when the body is not empty but contains a <div> already?
I've tried with the 'Browse Orders" template, that actually has the following already:
by adding the busyIndicator <div>, this latter appears at loading, but then remains on the screen once the page is loaded;
is there any solution for having the busyIndicator removed?
Thanks again and best regards,
JF
Hi Jepi!
In this case, I would probably try to find some component in the code that best represents the app, and have some code there to explicitly remove it from the dom.
In the typical projects I deal with, I usually have a main view with an top-level sap.m.App.
In that controller, I would implement the onInit() method and use plain dom to remove it:
If are not using a Controller, then you're going to have to find some place that you know will get called by the time you consider the application to be loaded and rendered.
(If it so happens that piece of code could get multiple times, you would have to make sure the busyIndictor wasn't already removed by a prior call.)
I hope this helps! Let us know how you fared 🙂
Roland.
Hi Roland!
thank you, it worked!
(using .parentNode)
thanks again! 🙂
Jepi