#012 Orlando thinks: When loading indicators remind me of fire detectors

Orlando Schäfer
arconsis
Published in
5 min readJan 17, 2023

Hello everyone, it’s me, Orlando. I’m an Apple fanboy and software engineer at arconsis. From time to time, I publish an article from the series “Orlando thinks” in which I highlight a specific topic that I see as important or exciting. Sometimes it might be just certain aspects of everyday life, but sometimes it might be tips, hints, thoughts, or appeals — but nonsense is not excluded either.

Someone holding a phone which displays the title logo of the blog article “Orlando thinks #012” and a loading spinner on the top.
(Photo generated with Placeit)

You know this? You are in a hotel or somewhere else overnight. You are lying comfortably in bed, and suddenly, a light flashes somewhere. You look around — nothing.

So you lie down again and try to sleep — There! Again! You look up … you stare into the void. And then you notice it with a deep sigh.

The fire detector.

I’ve never understood that. Why do fire detectors have to flash a red light every few seconds to say, “All good! There’s nothing wrong with me.” Why not report when something is not okay? Okay — admittedly, these models do exist. But that makes it even more annoying when you come across the other ones.

If something just works the way I expect it to — why do I need the feedback?

Things go wrong on the internet all the time

Unfortunately, things don’t always work. And when data moves from A to B, it’s common for something to go wrong. And there’s one fact that we can’t get rid of, even in 2023: Moving data takes time.

And this is where the loading indicator comes into play. So let’s be honest — loading indicators are just annoying. We only need them because we are still unable to shovel unlimited amounts of data around without any delay.

But then: I hit a toggle in an app that reports the new status to some backend system in the background. I don’t know exactly what it is: Either the amount of data is ridiculously small, or the developers really put a lot of emphasis on performance tuning. Or maybe I’m just not in Germany at the moment and don’t have to live with a lousy edge connection. Anyway, the request to the backend is fast, and the answer is back in no time. Everything works. Within — let’s say — 90ms.

And suddenly, I find myself back in the hotel room with the flickering light of the fire detector. Why? Quite simple: A loading spinner flashes briefly.

A quite annoying loading spinner that just flashes
A quite annoying loading spinner that just flashes

The tension field

Of course, we don’t know how long a request will take. But if we know that in 95% of the cases it will be so fast that I, as a user, don’t need any feedback — don’t show the spinner. So, according to the motto, “I’ll let you know if it does take longer”.

This brings us to the next problem. We now delay the display by — let’s say — 0.3 seconds. If the request takes 0.4 seconds I have the same problem again: The spinner flashes after 0.3 seconds for a tenth of a second.

Fortunately, there is a solution for this problem: Minimum display time. Mean, even if the request is already over, let’s display the indicator a bit longer so the UI looks smooth.

And so we stumble to problem no. 3: We show a loading indicator, although no more data must be loaded.

Congratulations, this is the tension field you are now in. It consists of the following 3 questions:

  • How long do I wait until I show a loading indicator?
  • How long do I show it then, at least? And…
  • … how much does this make everything feel a bit delayed?

Unfortunately, like so often, no solution is always right. And depending on which direction you choose, an implementation can also become infinitely complex. The latter is something you would like to avoid.

What is sufficient in many cases to keep the coding relatively simple is to use a debounce function. This delays a certain action if, after a defined delay, initial values have changed again. The classic application of this function is usually a search field where a user types a term. I want to wait with the request to the backend until the user stops typing. The disadvantage of debounce: The delay until I display a loading indicator and the duration it is at least visible is the same. But as I mentioned, this can be the solution for most cases.

Try it out!

If you want to experiment with debounce and the delay of loading indicators — check out my little iOS example project here.

UX is sometimes hard

Many UX aspects should be considered when implementing loading indicators. The following list, which is not exhaustive, shows some of them

  • Placement of the Loading indicator (e.g., show inline or modally)
  • The distinction between deterministic and non-deterministic loading indicators (progress bar vs. loading spinner)
  • Design of the loading indicator
  • Animation of the loading indicator
  • Time and duration of the display
  • … (things I forgot)

To find the correct answer for each point, you should ask yourself one question: In which context do I need a loading indicator? The context describes the content I am waiting for and the actions that lead me to this point. This results in an expectation. And as a developer, I have to live up to that expectation as much as possible.

That’s how it works for me. Those are the thoughts I have when implementing it. And in many cases, that’s enough to ensure that I’m not entirely off the mark with the solution.

And always remember: Best case is if you can avoid loading indicators at all.

Next time you find yourself at a place where you discover one of those flashing fire detectors — give feedback to the people who are responsible for that. Isn’t that something we developers also always request for our apps? ;)

Cheers
Orlando 🍻

--

--

Orlando Schäfer
arconsis

Passionate iOS software engineer from Karlsruhe. I am working @arconsis