#loading states

Loading states and loading experiences in general / 9 posts

Newsletter
  • Get a newsletter digest every Friday:
Contact

Send me feedback, tips, bug reports, and anything else:

About me and the blog

My name is Marcin Wichary. I’ve worked as a UX designer, typographer, front-end person, and manager at Google, Medium, and Figma. I’ve also written a book about keyboards and typing, gave talks, and published essays about design, typography, and technology.

Unsung is my blog about software craft and quality.

More info about Unsung

Send me feedback, tips, bug reports, and anything else:

More info about Unsung

A loading state within a loading state

1.

One of the classic parables about loading goes as follows.

A building manager had a problem: people were complaining about the elevator being too slow. But upgrading the elevator was an enormous expense, so the manager came with an alternative solution: they put a mirror next to the elevator call buttons. Even though the elevator didn’t become any faster, complaints trickled to a halt, as people were checking themselves out in the mirror and that changed their perception of how long the wait really was.

2.

In the late 1970s and early 1980s, it wasn’t uncommon to equip early home computers with audio tape players, using the same cassettes designed to record and play music. Software was encoded as sound. A lot of redundancy was needed to account for many low quality cassettes and misaligned playheads, so loading times were really long. There were other disadvantages – no random access but definitely random errors, tapes wearing out and being “eaten” by the player – but tapes were so much cheaper than floppy disks or cartridges that they endured.

On one of the computers, the British ZX Spectrum from 1982, an interesting convention emerged. As the game was arriving from the cassette, what was loaded before the code itself was its “title card.” The loading process of just this one image took about 35 seconds, and watching the graphic emerge was mesmerizing, almost like deciphering a puzzle – especially when, only toward the end, the color attributes appeared and the whole thing clicked into place:

Some of these were beautifully done (here’s a gallery of… all of them?), created by talented artists working in a very unforgiving medium, a pleasure to watch materialize on the screen…

…or, at least, it felt so for the first few encounters. Upon loading the game for the nth time, you grew more and more aware of the fact that you are spending precious time waiting to load a screen you’ve already seen. This was different than the first example; the mirror existing never slowed down the elevator.

Sure, it was just 35 seconds out of a 5–20 minute load time – I told you cassettes were slow! – but still. Some people loved them, others built truncated versions that skipped the title screen altogether (as much as you could imagine just fast forwarding through it like you would through a song, it didn’t work that way).

3.

Figma is a web design app, and its editor arrives in a big, everchanging blob of JavaScript, in addition to having to load and decode the contents of the file itself. This isn’t 5–20 minutes, but it’s long enough that it necessitated a loading screen of the heavy variety: one with a progress bar.

During my time at Figma, an idea would reappear with surprising regularity: what if we put a little hint next to the loading bar? Something that could teach you about a useful keyboard shortcut, or a trick? You’ve seen that before, often in games:

It seemed like a thoughtful gesture for the user, a mirror of the elevator mirror idea. But I fought it, tooth and nail, for one very specific reason: this would remove pressure to make this screen fast.

Had we given the screen another purpose, subconsciously or not, we might start caring less about improving it – as a matter of fact, you could make an argument to introduce artificial minimum loading time just so that the user could finish reading the tip!

4.

I had a similar feeling when, in 2018, Gmail replaced its simple progress bar loading state with this:

It was huge, corporate, intense. It felt like an admission of defeat: our app is slow, and I guess we’re surrendering ourselves to it.

But recently, I’ve noticed not just that Gmail’s loading state has been simplified, but also that it doesn’t appear nearly as often:

I don’t know the technical details: is it caching? a more intense refactor? Either way, as much as I absolutely dislike what Gmail has become – there might be no more harrowing place in the web app world than Gmail’s settings, for example – kudos to the team for making it better. Gmail seems to be loading a lot faster now.

(There is one small exception: it would appear that the loading state image itself doesn’t have a proper loading state – a rather strange omission.)

5.

There is, I believe, a more universal lesson in here.

Loading is a complex space, where sometimes the most natural solution is a bad one, sometimes making things faster is making things slower, and sometimes new thoughtful design for whatever delay there is can be a better use of engineering effort than focusing on shaving off more milliseconds. (It’s both speed and the perception of speed that matter.)

Also, this is exactly what Y2K was: We remember and react to loading states that are elaborate, cute, memorable – but we never see or link to loading states avoided.

And while you see occasional stories told by engineers making things faster, you don’t often hear accounts of people within companies, somewhere at the intersection of design and engineering, who work hard designing thoughtful loading states, avoiding loading state bloat, or figuring out some clever hybrid approach.

But, to be fair, there is also no parable of a building manager who just forked over some cash and installed a better elevator.

“Act now, apologize later”

Fighting games require rather precise timing: the action is frenetic, the inputs rapid, and the outcomes can be determined by what players do down to – sometimes – individual one-sixtieth-of-a-second frames.

This is fine when you play locally, but gets infinitely more tricky the moment you attempt to kick someone’s more remote ass:

Information sent to your opponent may be delayed, arrive out of order, or become lost entirely depending on dozens of factors, including the physical distance to your opponent, if you’re on a WiFi connection, and whether your roommate is watching Netflix.

The part of the game responsible for dealing with networking is called netcode, and the classic solution to the lag problem has been delay-based netcode with a sort of lowest common denominator approach: if your opponent has a “ping” of 50ms, your actions will also be delayed by 50ms, to ensure fairness.

It’s not that hard to imagine many problems with this idea. Lag comes and goes but the game doesn’t smooth it out, the play feels like jello with even an okay connection, and the game occasionally freezes, waiting for a suddenly dropped connection to resume, not knowing what to do in absence of information.

That’s why within the last decade, what gained popularity is a new kind of netcode called rollback netcode, which operates by… lightly predicting the future. Most of the time, within a reasonable lag, the game will feel as fast as a local game to both players – and even when the optimistic prediction doesn’t match what eventually happens in reality and the code has to roll it back, visibly, in front of a player, the change might be too small to notice and only rarely it’ll result in rubber banding.

Core-A Gaming has a great video about specifics of rollback netcode:

It covers a lot of stuff, including nuances like drift and design decisions that game makers might want to incorporate to soften rollback netcode’s most annoying side effects. (Also, the guitar playing bit at 0:22 is absolutely brilliant.)

The video is largely based on an earlier essay by Infil, which has even more details (audio!) and which I excerpted above.


It’s not just videogames. When Apple announced in 2019 that they reduced the latency when using their iPad Pencil from 20ms to 9ms, they didn’t hide that they had to peek into the future as well:

The specifics were, as far as I know, never revealed. But the fact that some of the input events the app receives are not actually real is official and documented:

It takes time for UIKit to generate and deliver touch events to your app, and it takes time for your app to process those events and render the results. In fact, it takes enough time that there can be a visible lag between the movements of a person’s finger or Apple Pencil and the rendered results. To minimize the perceived latency between touch input and rendered content, you can incorporate predicted touches into your event handling.

In fighting games, the most accurate prediction is a trivial “whatever buttons and controls the player holds on the current frame are likely the same they will hold on the next frame,” but for other games – and for Apple’s Pencil – slightly more advanced prediction might be necessary:


It feels disappointing that no matter what we do, there might be no way to reduce latency below a certain threshold without cheating.

But if there’s any consolation, it’s that cheating seems to be the only answer, and that has been the case long before computers came aboard. There are many documented ways our brains have their own netcode to cover for various lags occurring within our bodies. There’s the stopped-clock illusion, the cutaneous rabbit effect, the color phi phenomenon, and – most relevant for today, even though it has the most boring name – the flash-lag effect, documented on this nice page by Michael Bach:

The flashing lines are shown exactly at the same time and angle as the rotating line, but it certainly doesn’t appear to be the case. Just like fighting games and Apple Pencil do, our brains predict and extrapolate the movement of the moving line so that our other senses can intercept it at the right moment. The go-to example of why it’s needed is that you wouldn’t otherwise ever be able to catch a ball thrown your way – but I imagine it might be useful in a street fight, as well.

For a lotmore technical aspects of rollback netcode, check out this long conference presentation from GDC.

Flickr’s optimistic committing

Somewhere next to optimistic loading and optimistic saving exists another technique to make apps feel faster: optimistic committing.

Flickr is a great example. After navigating to photo upload, you enter a sort of a foyer where you can drag in the photos, reorder them, name and tag them, and otherwise prepare them before pressing the big Upload button.

But Flickr also optimistically assumes you will press that button, and slowly starts uploading the heavy photos in the background the moment you drag them in.

Like all optimistic schemes, being friendlier toward the user complicates things for Flickr’s designers and engineers. After all, there is still a regular upload modal after you do commit to the upload…

…so the two states – quiet staging area upload, and the official visible upload – have to be reconciled and kept in sync.

Also, optimistic but eventually cancelled uploads have to be cleaned up from the servers.

Lastly, there’s signposting. Contrary to lighter optimistic loading schemes, which typically simplify reality by pretending no data transfer is actually happening, the optimistic committing here is actually visible through small indicators:

I think this transparency is welcome. In the past, Meta (who else!) got into hot water for abusing optimistic committing:

Did you ever record a video on Facebook to post directly to your friend’s wall, only to discard the take and film a new version? You may have thought those embarrassing draft versions were deleted, but Facebook kept a copy. The company is blaming it on a “bug” and swears that it’s going to delete those discarded videos now. They pinkie promise this time.

In this context, it’s good that Flickr conveys data is being sent to the servers; I believe this helps with building trust.

On top of transparency, I think it’s also good that this process shows the progress of uploading with a lot of precision – not just between files, but also within each file. Internet connection speeds vary so much, not just geographically, but also even situationally, that this is really helpful in practice. There are many moments where auto saving to the cloud needn’t bother the user unless the connection goes offline for a longer while, but this feels like a situation where clarity is better than magic.

Fingers already on the keyboard

This is what happens when you go to the homepage of Gemini and start typing quickly:

Mechanically, I think this is React or some other framework setting focus again with some delay, but the end result is… rather disturbing.

While the technical solution would be to fix the problem or at least do not set focus again if already set, I wonder what’s the real challenge here. I imagine it might be that the testing process (if any) assumes using the mouse or trackpad first. In this case, moving the hand to the keyboard to start typing gives the interaction just enough delay to miss the second, unnecessary focus.

I think a good assumption to have for all common interactions is that for some users, fingers are already on the keyboard and things can happen so much faster than you expect.

Not accounting for that, the creators of this flow inadvertently broke one of the cardinal rules. We talked about it in the context of mouse pointers before, but it applies as well to text: don’t move my cursor for me.

“Area connected to a given node in a multi-dimensional array with some matching attribute”

Anyone using old computers for graphics remembers the strangeness of “flood fill”:

The 1950s and 1960s computers were so sluggish that their consoles with blinking lights were not just for show; the operations were slow enough that you could still follow the lights in real time.

This ceased to be true soon afterwards. The microcomputer revolution temporarily reset some computing progress, but by the 1980s and 1990s more and more things were happening too fast for us to keep up.

But here (this above is Paint in Windows 1.0, and you can try for yourself in a browser!) was one example where you could still see an algorithm working hard. It was mesmerizing and educational, and it was a rare example where perhaps you didn’t mind the computer taking its sweet time. Even messing up like I did above – maybe especially messing up – ended up fascinating to watch.

Wikipedia has examples of a few different flood fill algorithms, which are even more interesting:

A few years later, Minesweeper had a very memorable flood fill, too (also available in a web emulator today):

But by now Minesweeper retired from sweeping mines, and today computers are so fast that it’s hard for me to imagine any flood fill being anything else but flash flood…

…except this is what I just saw in Pixelmator on my Mac:

I don’t know if this is a nod toward a classic flood fill, or just a nice unrelated transition. But I found it genuinely delightful, and it’s fast enough that I would imagine it doesn’t bother pros who need to do it often.

Sometimes it’s nice to see a computer working when there’s a good reason; some apps like banking apps even insert artificial, visible delays after crucial operations, just so that the users feel comfortable knowing their important transaction went through.

But sometimes it’s nice to see a computer working for no reason at all.

“One of the smaller but downright disturbing issues with dark mode”

As a Mac user I naturally focus on that platform, but Windows 11 has had its own share of problems – and that list has grown so vast it’s hard to know where to start.

So let’s pick it up at random, with a post by Thom Holwerda with a great title “You can actually stop Windows Explorer from flashbanging you in dark mode”:

One of the most annoying things I encountered while trying out Windows 11 a few months ago was the utterly broken dark mode; broken since its inception nine years ago, but finally getting some fixes. One of the smaller but downright disturbing issues with dark mode on Windows 11 is that when Explorer is in dark mode, it will flash bright white whenever you open a new window or a new tab. It’s like the operating system is throwing flashbangs at you every time you need to do some file management.

I find the videogame-inspired nickname darkly – I’m sorry! – funny, but the problem is real. It looks like this (video via windowscentral.com):

It’s not a problem unique to Windows 11 – just the other night I saw this on Wikipedia on my iPhone, exacerbated by the delayed reaction of Liquid Glass buttons spastically adapting to the changing background:

But there is something about this that feels a notch more important than other visual and layout issues.

I think this is because dark mode is a contract – we’ll lower the brightness, and we’ll let your eyes rest. There’s a physiological part to it: a sudden flash of light when your eyes are not expecting to it can be actually physically painful. I think it’s worth thinking about it and futureproofing and sanding dark-mode views especially at their edges: loading states, error messages, signing in and logging off areas. The “flashbang” analogy is very apt, and especially so on bigger screens.

A tale of two import windows

Bear – beautiful, whimsical, delightful, but dry on the details. This window was on the screen for many minutes:

Obsidian (or, at least, the suggested Obsidian Apple Notes import plugin) – functional, informative, precise, but a bit on an uglier side:

As the meme goes, why not both?

The original loading state

I spend a lot of time at work thinking and designing (and avoiding) loading states, and someone just reminded me of a piece I wrote ten years ago, so I just moved it from Medium to my new website, and updated with new things I learned.

It’s about TV clock idents and what they meant to me growing up – possibly the original “loading state” in my life.

Of course, really, nothing compares to the absolutely banging BBC News “loading state”, which is fantastic, infinitely memeable, and brilliant even before you realize it cleverly incorporates the historical Greenwich Time Signal in it in a way that absolutely gives me chills.

Best comment under that BBC News theme: “As a swiss, this makes me proud to be british.”

What is it about Brits and extraordinarily perfectly timed music? Here’s Pet Shop Boys and Casting a shadow, made especially for and matching the total solar eclipse in 2000 to within half a second.

“How can I delete and add to library at the same time”

An absolutely eviscerating 18-minute walkthrough of Apple Music for macOS Catalina, from a few years ago. More funny than anything else, but a reminder to test the “boring” edges of your app – like a state with a lapsed subscription, or coming back after a few months.

There’s no way to drag and drop. […] If I want to add this to here, I have to go through this bullshit, and when I do, it takes seconds again.

Also, an ode to a well-functioning back button, and well-behaving loading states. Those things add up so quickly.

(My debugging brain understood what populated the confusing History entries – I bet it was the early play sequences that went through a bunch of stuff without playing.)