mirai gadget labahmedabad

how much work can a loading indicator possibly be?

We were redesigning our app’s UI, and I wanted to give the loading spinner some love.

It seemed like a small, enjoyable bit of work. I found a dot-matrix loader that looked cool and thought it would be a nice detail to bring into the redesign.

Several versions later, I ended up with a simple progress bar across the top and a dot-matrix spinner on the right. Getting there involved two dotted lines, a notch, an aurora, and a lot of opening staging and changing my mind.

Some context: this is a dense, multi-tenant B2B application built with Laravel and Inertia. There are plenty of queries and aggregations behind the screens, and some interactions take a moment. People need to know that their click registered and the app is doing something.

Our audience is mainly busy business professionals. They’re in the app to get through their work. They shouldn’t have to look around the screen to figure out whether anything happened.

We already use loading spinners on buttons and skeletons in slideovers. Extending that kind of local feedback to every interaction would have meant a much larger refactor, which is another story. I also wanted a global indicator for work that didn’t neatly belong to one button.

It started with dots

The first version put the dot matrix in the top-right corner, beside the account menu. I really liked it. The dots had a bit of character, and it felt like a small detail that had received some attention.

The first version: a dot matrix beside the account menu. Animation replayed from the original styles.

The problem was that I knew exactly where to look. Someone clicking a link elsewhere on a busy screen might never notice it.

So I tried carrying the same idea into the progress line at the top of the page. One row of dots, with a brighter band pulsing along it. It looked okay, but it was still too easy to miss.

A single dotted progress line. Animation replayed from the original styles.

My next idea was to add another row.

Two rows looked terrible. They were more visible, certainly, but the extra green pixels across the top made the whole thing feel clumsy. I wanted clear feedback, and I was getting a very conspicuous dotted border.

The two-row experiment. Animation replayed from the original styles.

A small island

I work on a MacBook and have Alcove installed. It gives the notch a Dynamic Island-style interface for notifications and other activity. Around this time, a meeting notification popped up there, and I thought: we could do something like that.

A little notch dropping out of the top centre of the app would give the loader a consistent, obvious home.

I played with the shape, spacing, and animation, trying to get that smooth spring feeling. It was super cool. The dot matrix sat inside the notch, which dropped down when something was loading and tucked itself away afterward. I was happy to ship that version.

The refined notch, with a spring entrance and a dot-matrix spinner. Animation replayed from the original styles.

Then I opened our staging preview and started navigating around.

The notch appeared on every navigation that lasted long enough to trigger it. Something that felt lovely when I replayed it in isolation felt surprisingly jarring when it kept dropping into view as I moved through the app.

There was also a timing problem. I had set a 300 ms delay before showing it, so immediate interactions wouldn’t get an unnecessary loading animation. But plenty of interactions finished in under a second. If a request ended shortly after that threshold, the notch barely had time to appear before it disappeared again.

That gave me a flicker instead of the smooth animation I had spent time on.

I added a minimum visible time: once the notch appeared, it would stay for at least 1.5 seconds, even if the request finished sooner. That applied to the indicator; the page could become usable while it was still visible.

It looked much better. But as I kept navigating, something still felt off. The timing was calmer, yet the repeated appearance kept drawing my attention. I couldn’t quite settle on it, so I parked it for a bit.

The aurora phase

Later, while browsing the Effect blog, I noticed a ripple-like animation in the top bar. That gave me another idea: what if the loading state lived in the header itself, using the same dot-matrix style?

The first attempt looked nice, but again, it wasn’t clearly visible. So I expanded the dots into a grid that occupied the whole top bar. I added a fade toward the bottom, then replaced the simple pulse with an aurora-like animation moving through the grid.

I really liked this one. It gave the header a bit of life without needing a separate shape to drop onto the screen. I shipped it into the preview and started using it.

The dot-matrix aurora across the header. Animation replayed from the original styles.

And, after a while, it got annoying too.

There is a big difference between watching an animation because you made it and seeing it repeatedly while trying to do something else. I kept enjoying the first few appearances and judging the design from those. A longer session in staging gave me a much less flattering view.

The header was moving while I was trying to read the page. Every navigation was another little performance. The actual content already had plenty going on, and I had given the loading state a generous share of the screen and my attention.

Back to a line

I was testing all of this in Dia. At some point, I noticed its simple progress animation and thought: let’s just stick to something like that.

So I landed on a thin progress bar across the top, with a brighter leading edge and a softer trail, plus the dot-matrix loader on the right.

The final direction: a simple progress line and a corner dot matrix. Animation replayed from the original styles.

The line gives an immediate sign that something is happening. The dot matrix keeps a little of the character that started this whole exercise. There’s no notch arriving in the middle of the header, and no field of dots moving behind the navigation.

It felt much more comfortable as I moved around the app. I could register the feedback and carry on looking at the thing I had actually opened the page for.

What I took from it

The most useful test turned out to be continuing to use the app after the animation stopped being new. I could make almost any of these versions look good in a short preview. Repeating the same ordinary navigation over and over made the tradeoffs much easier to feel.

Visibility and distraction needed to be considered together. The corner spinner was easy to miss. The notch and aurora were easy to notice, but also hard to ignore. I had spent a lot of time moving between those two problems.

Timing mattered just as much as appearance. The delay and minimum visible time changed how the notch felt without changing its design. They also introduced a tradeoff: preventing a brief flash meant keeping the indicator around after some requests had already finished. Those values deserved the same attention as the spring curve.

I also learned something about borrowing ideas. A meeting notification in Alcove is meant to pull my attention away for a moment. A loading indicator that appears throughout an ordinary session has a different job. I loved the reference, but I needed to account for how often our version would appear.

I’m glad I tried the more elaborate versions. They helped me understand what I wanted from the simple one: feedback that is easy to notice, easy to understand, and comfortable to see again and again.

I started out wanting to give the spinner some love. Apparently, that involved giving it a few increasingly elaborate personalities before asking it to calm down.