For a more conspicuous SPA loading indicator

// The french version of this article can be found here: Pour un indicateur de chargement SPA plus visible.

Since version 7.0 of Liferay, you surely noticed the apparition of a thin loading bar on top of screen, after most of user actions.

This loading bar is part of the new SPA (Single Page Application) mode of Liferay, supported by the Senna.js framework.

Unfortunately, this bar is so inconspicuous that most users do not see it. In general, without a visual feedback related to their action, they reiterate their action several times, which often lengthens the waiting time.

In the end, users are often unnecessarily frustrated just because this load indicator is not visible enough.

Fortunately, it's quite simple to fix this with a few lines of CSS in a custom theme, because this loading bar is just a single HTML tag on which a CSS class is dynamically applied.

<div class="lfr-spa-loading-bar"></div>

As a starting point, we can consider the superb loaders provided by Luke Haas in his project Single Element CSS Spinners. Just make some adaptations to get a CSS loader compatible with Liferay:

/* Reset properties used by the original loader */

.lfr-spa-loading .lfr-spa-loading-bar, .lfr-spa-loading-bar {
    -moz-animation: none 0 ease 0 1 normal none running;
    -webkit-animation: none 0 ease 0 1 normal none running;
    -o-animation: none 0 ease 0 1 normal none running;
    -ms-animation: none 0 ease 0 1 normal none running;
    animation: none 0 ease 0 1 normal none running;
    display: block;
    -webkit-transform: none;
    -moz-transform: none;
    -ms-transform: none;
    -o-transform: none;
    transform: none;
    background: transparent;
    right: initial;
    bottom: initial;
}

/* Pure CSS loader from https://projects.lukehaas.me/css-loaders */

.lfr-spa-loading .lfr-spa-loading-bar,
.lfr-spa-loading .lfr-spa-loading-bar:after  {
  border-radius: 50%;
  width: 10em;
  height: 10em;
    z-index: 1999999;
    
}
.lfr-spa-loading .lfr-spa-loading-bar  {
  margin: 60px auto;
  font-size: 10px;
  text-indent: -9999em;
  border-top: 1.1em solid rgba(47, 164, 245, 0.2);
  border-right: 1.1em solid rgba(47, 164, 245, 0.2);
  border-bottom: 1.1em solid rgba(47, 164, 245, 0.2);
  border-left: 1.1em solid #2FA4F5;
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-animation: load8 1.1s infinite linear;
  animation: load8 1.1s infinite linear;
}
@-webkit-keyframes load8 {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@keyframes load8 {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

/* Positionning */

.lfr-spa-loading .lfr-spa-loading-bar {
  position: fixed;
  top: 50%; 
  left: 50%;
  margin-top: -5em;
  margin-left: -5em;
}

Once the custom theme is applied we get a loader clearly visible that no user can miss:

This snippet support Liferay 7.0 and 7.1 and is also available on gist.

If you also have tips to improve the UX of a portal Liferay, feel free to share them in the comments of this post or in a dedicated blog post.

Sébastien Le Marchand
Freelance Technical Consultant in Paris

Blogs

This article was very helpful. I been looking for way to add/change a page load indicator. The code provided worked perfectly. Thanks!

Thanks for sharing ! It works perfectly.  

I was looking about the progress bar styles that Liferay incorporates by default; but this article goes further.  

Thank you

Hi, I have implemented your code and it's working fine. Thanks for the article.

I'm trying to change it to some other loader, but I couldn't able to acheive it,

In this page https://projects.lukehaas.me/css-loaders , I want to implement 2nd loader into my liferay project. Please help me with the code changes. Thanks in advance.