Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
roland_bouman
Contributor
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:

Screenshot of the loading screen

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!
11 Comments
mattredfig
Participant
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?
roland_bouman
Contributor
0 Kudos
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
0 Kudos
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

Where can we find more info on this? This does not work out of the box on OpenUI5 V1.84
roland_bouman
Contributor
0 Kudos

Hi Dimitar,

 

does it work for you with the sample app?

 

https://github.com/just-bi/ui5tips/tree/main/loadingscreen

0 Kudos
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:
  <body class="sapUiBody">
<div id="busyIndicator">
<div>
<h3>App is loading</h3>
<h4>App lädt</h4>
<img
height="250px"
width="250px"
src="assets/splash.svg"
/>
</div>
</div>
<div
data-sap-ui-component
data-name="com.myorg.myapp"
data-id="container"
data-settings='{"id" : "MyId"}'
></div>
</body>

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.
roland_bouman
Contributor
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.

 

 
wridgeu
Participant

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...

more specifically here in this line: https://github.com/SAP/openui5/blob/097469704f7c00e5d2c138d8a2001c97ccbc72a4/src/sap.ui.core/src/sap...

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...) during rendering of the root.

Great blog post! It was the reason for me to look into this in the first place! 🙂 

BR

Marco

roland_bouman
Contributor
Hi Marco,

 

Thanks for the kind words, and thank you so much for the insights! Much obliged.
jepi_flanders
Participant
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:
<!-- UI Content -->
<body class="sapUiBody">
<div data-sap-ui-component data-name="sap.ui.demo.orderbrowser" data-id="container" data-settings='{"id" : "orderbrowser"}'></div>
</body>

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
roland_bouman
Contributor

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:

 

onInit: function(){
var busyIndicator = document.getElementById('busyIndicator');
busyIndicator.parent.removeChild(busyIndicator);
}

 

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.

jepi_flanders
Participant
Hi roland.bouman!

thank you, it worked!

(using .parentNode)
onInit: function () {
var busyIndicator = document.getElementById('busyIndicator');
busyIndicator.parentNode.removeChild(busyIndicator);
},

thanks again! 🙂

Jepi
Labels in this area