In modern web applications loading animations are an important part of the User Experience (UX). The User needs to know that something is going on – even if loading is usually very fast.
In early prototype development developers and product owners tend to omit any loading indicator. This is totally fine until first real users try the app. They may get confused and try to hit the refresh button or repeat button clicks. If a request is very fast, they might not notice that the content has changed and wait for something to happen.
Common Global Loading Indicator
The next step usually is to include one of the many common loading spinner libraries (eg. CSS-Loader). They are easy to use, work in every modern browser and look kind of fancy. A common pattern is to show the spinner during every HTTP request (eg. with Angular Interceptors). Again, this is totally fine for early stages of app development.
So, what’s wrong with that?
Firstly, those spinners often come as modal overlays disallowing the user to interact with anything of the app. But if you implemented your single page app correctly, most of the elements should work even if some asynchronous loading is going on. Navigation items, drop down boxes, abort buttons and many more elements still work and should not be disabled. Think of a user that triggered the content loading mistakenly. She is not able to abort it or to leave the page for the originally intended one.
Secondly, the global loading spinners are often located in the center of the page where they aren’t coupled to the position of the soon-to-come content. This causes the users to lose their focus. They click, focus the center of the page for a short time and then have to refocus the previous element which might look different now. So, like with popups, modal screens should be used with care. Always ask yourself: Is there a reason to take the user’s focus away? This might be true if something unexpected happens but loading of content isn’t.
Inline Loading Indicator
A fair alternative are inline spinners; very small animations located near the action element or even inside buttons (eg. this one). They are fine. The user knows something happens and her focus doesn’t get distracted. Buttons usually get disabled during load so that impatient users don’t trigger writing transactions more than once and cause race conditions. This might be a good idea anyway — no matter what type of loading indicator you choose. But when the resulting content loads somewhere else you miss the chance of preparing the user for where the result is displayed.
Content Loading Indicator
Displaying a note or an animation at the position where the real content get’s loaded after the request works best for highly asynchronous apps. Imagine a page with lots of independent tiles or cards that load from different endpoints. Each tile shows a note until the content is finally there. But too often this kind of indicator replaces the content with something completely different.
Does it get any better? It does, with the…
Facebook Inspired Content Aware Loading Animation
Facebook was one of the first to implement a loading animation that looks just like a simplified version of the real content. It is a lovingly animated content loading indicator that prepares the user for what is yet to come. Will it be an article? A table? An image or chart? You as developer know the content type so it is easy for you to design an indicator preview. Another advantage is that this animation feels just as if it’s already there. It’s so close, you can almost feel it.
There are some tutorials out there on how to implement this kind of indicator. But most of them (like this one) tell you to create a large animation and mask the white parts with lots of small
divs. This soon gets tedious and doesn’t scale very well. I found another option: SVG with masks. Instead of modeling the white part (the negative) with SVG masks you can model the animated parts (the positive) as normal SVG elements. Even polygons, circles or text is possible. But there is more: SVG work with percentage values, too. With percentages you can create a fluid layout that adapts to the screen size. Another advantage is that you can compose SVG with any template engine to dynamically create layouts.
Every browser since IE9 supports SVG images out of the box. SVG code can easily be placed inside your HTML files because it is a valid XML-like HTML element. I created a few examples you are free to use, adapt and share:
„Facebook Card“ Example
Chart with Caption
We talked a lot about indeterminate asynchronous tasks. Tasks of which we don’t know the current progress. But whenever possible you should inform the user about the progress of the asynchronous task especially when it takes some time (determinate task). Downloading large files or processing huge amounts of data might be good examples. There are approaches out there that try to fake this behaviour by slowly stepping through the progress and waiting at 90% until the tasks completes. This might look fancy most of the time but not until something really takes longer than expected. The bar stops near the end and the user gets impatient. So, if your task is indeterminate don’t lie to the user.
But even with indeterminate tasks you can tell the user if something is wrong by implementing two timeouts. One fires when the request takes longer than usual. If something takes normally around 1 second and this time more than 5 seconds you should inform the user that there is something wrong and what the user can do („This request takes longer than usual. Please check your internet connection or try again later.“). The other timeout fires when there is really no hope that there is anything ever coming back from the server. Default timeouts are 30s or 60s. But you should adapt those thresholds to the kind of tasks. No one will wait 60s for a page to load. If the server is down, the server is down. Don’t let the user wait forever. Instead redirect her or tell her what she can do.
So, we talked about the pros and cons of different loading indicator approaches. A topic that — in typical application development processes — comes up way to late. There are deterministic tasks where you should use a real loading bar and indeterministic tasks where you should tell the user as much as you – as developer – know. And you know a lot: Where will the new content be placed? What type of content is it? How long does it usually take to load? What can the user do if it takes longer? What if it takes too long?
If you put all these things together, prevent mistakes or race conditions and create a fancy animation on top like one of my examples above the users won’t get bored because loving software is often because of the details.