The perpetual spinner thing happened at my last job too, and I developed the opinion that putting a spinner into your site at all is a sign of incompetence. For any normal CRUD app, it should take milliseconds to do whatever task. Even with network delays, 150 milliseconds is a reasonable upper bound for end-to-end processing. If you have an animation at all, then your thing is either ridiculously slow or broken. Either way the animation is a crappy attempt to paper over a bad job.
As an Australian whose parents have 300kbps internet, please continue to add spinners to your apps. The round trip time to US west is 270ms for a good connection here. That 270ms doesn't include any processing (maybe 60ms or so) and the wifi tax (another 20ms). Then your round trip time gets doubled by HTTPS, which goes up to tripled if you're sending more than 14 KB of data.
This means it takes a full second to load most websites or apps, and this is further compounded by slow server code, daisy-chained sequential calls, living further away from the undersea cables, and bad infrastructure.
Imagine the entire UI of an email client becoming inoperable, diplaying "loading..." and a spinner every time you send mail. We don't do it now nor did we do that when 300kbps connections were more common. Spinners are a crutch for undercooked, bad software.
From what I remember of Thunderbird and Outlook, they both showed a visual loading indicator somewhere in the UI.
Am I missing a detail of terminology here? By "loading spinner" I meant it in opposition to "do absolutely nothing for three full seconds and make me refresh the page with the network tab open." I didn't mean to suggest any particular indicator of a pending network request, only that there should be an indicator.
Yes see what you mean now. Sorry - I was imprecise with my wording. As a fellow Australian I feel the pain too by the way :)
> do absolutely nothing for three full seconds and make me refresh the page with the network tab open
This is what I was talking about. A pattern I see is papering over this deficiency with a massive “spinner”. Barely noticeable for the devs accessing the app on 127.0.0.1 on fancy machines - so frustrating for everyone else.
Absolutely agree indication of activity is important. Especially so considering how buggy many of these web apps are.
And ndriscoll is also unfairly generalizing. Which usually happens when you generalize because it's impossible to take all eventualities into account.
For example, I've worked on add-ons to other software. But it's cloud and you gotta make certain calls back to your "host" app. Said host app responds to most calls in more than the 150ms they claim is the max. Because of what guarantees our plugin makes to the user and despite us caching whatever we can we need to make multiple such calls to make our guarantees... well guarantees.
So what can we do? Of course we show spinners while we make those necessary calls and make absolutely everything we can get away with async.
But we can't get away from things potentially taking more than a second when something isn't in cache, the host app is slower than usual and under 150ms is impossible for anything that doesn't just hit our own database.
Spinners don't have to replace the entire UI or make it inoperable. Classic email clients did indeed have a losding indicator when doing things like a "send and receive" operation.
Keep in mind that spinners can also be used (as well as other indicators) that something is being processed client side, e.g. rendering a video and if the total time can't be estimated a spinner is reasonable.
Processing should be more like 6 ms though (assuming basic CRUD), not 60. The TLS/TCP latency can be solved with a TLS terminating proxy in the region. After that, unless you want spinners on every data fetch (a miserable experience), you probably want a read replica if you're actually trying to serve the region. If you're a big company, you probably want a full read/write setup in the area (which is something for big companies to figure out anyway with newer data protection laws).
Slow server calls and daisy chained sequential operations are both people doing a bad job. My last job had backend calls that took over 1s to do basic CRUD on a low traffic service (bouncing around a dozen micro services on the backend). That should never happen.
> For any normal CRUD app, it should take milliseconds to do whatever task. Even with network delays, 150 milliseconds is a reasonable upper bound for end-to-end processing
This is only really true with stable, high speed internet connections. We still cannot take for granted that everyone has that, especially not in rural areas and double especially not on mobile devices
So many places in apps just wait for no reason. Let's take a hypothetical situation:
Suppose you're doing gig delivery. You're delivering to two customers in the same neighborhood on the same run. You drop the first order, take your photo of the drop, and the app spins. It's waiting for the photo to be delivered before it moves on. You can't get directions to the next customer until the app moves along. Why can't it just take the photo, take the text description, and hold that until service is better? Just give the driver the map, and upload the other stuff when you can.
I have similar issues with every app. It seems like every user interaction, every button press requires a round-trip to the server before the app moves to the next step. There's no reason for this. I wager that every app can keep its UI and the user's data locally, and send and receive teensy data updates.
But all "the best" software development employees (that they claim their hiring process hires) in these companies can't seem to work that out.
While doing Instacart deliveries here in Maine, I dropped off a leave-at-the-door order which requires uploading a picture of the shopping bags at the entrance. However, there wasn’t any service in the rural area I was delivering to, and the app required a connection to even open the camera interface. So I had to drive away down the road until I had service, open the camera, drive back to the delivery point, take the picture, then drive away again to upload the picture and complete the order.
They require a mobile phone number now. If I give them one, they'll enforce SMS as a login path.
I live in an area with excellent cell service, except for a few miles around my house. I'm not going to try to log in, while buying something, then drive down the road and wait for the SMS.
The whole point of having an app is to collect data, show ads, and “engage the customer with the brand.” Any additional capabilities beyond that are incidental.
The delivery driver is not the customer, but I wouldn't be surprised if some MBA bonehead thought showing ads to workers was a win. "They have to use the app to schedule and do the work, so it's a captive audience!"
Hell, I got shown an ad after I paid for a ride on Lyft the other day. Even if you’re the customer, you’re still the product. If there’s not already ads in the drivers’ views, I’m shocked it’s taken them this long.
Why do you think only MBAs have the idea to insert ads? It's not exactly specialized thinking. Plenty of startup founders with technical chops decide to insert ads because they desperately need the revenue.
Because "MBA" has become a generic derogatory term for greedy and short termist management, because its easy to blame a group of people than face the fact that the problem is a wider one of incentives and ethics that pervades the whole of western society.
> Why can't it just take the photo, take the text description, and hold that until service is better? Just give the driver the map, and upload the other stuff when you can.
The obvious answer is because asynchronous workflows are brittle, and require intervention from the end user to correct if they break
Then most end users aren't going to care to fix it when it breaks, or be able to fix it when it breaks for a variety of reasons
Better they can't continue than they do the last order wrong, amirite?
There's some strong "Seeing Like a State" vibes here. I'm pretty sure these apps are intentionally designed as tools to force the users (here, drivers) into a specific flow, a flow that minimizes complexity for the vendor, reality be damned.
Another way to look at it: the job of the driver side of a delivery (or taxi) app isn't to be useful to the driver; the job is to be a remote control with which the business can control the driver like they were an automaton.
It's dispute resolution in a low-trust environment.
When a customer shows up saying something went wrong with the delivery, the CSRs will need evidence and if the driver did their job then they can be exonerated.
The logistics are a bit more complex than a restaurant where customers are eating at tables in the same building.
Lots of delivery jobs are effectively paid by the piece or paid by the route. The driver is not paid hourly.
This is one reason that package delivery drivers often will say that they've attempted delivery when they at best drove past the delivery point. Marking the delivery as attempted gets them off the hook for that delivery, and they can finish their shift that much faster.
Having a broken app that forces the driver to 100% complete every delivery before moving to the next one thus costs the company relatively little, but saves some complexity, missing proof of delivery, etc.
You can still queue the upload client side and let the worker move on. Don't consider the delivery complete until the upload happens, but allow the next leg of the job to start. The client workflow can require taking the picture and clicking submit, but it can accept queueing the actual upload.
In any case, if the network is down, a spinner is a lie. It's pretending to be working on something when it's not. It should show an error at least.
Relevantly, in this specified case, the picture of their delivered food is shown to the customer immediately. This is more than a nice to have (imagine a large apartment building, where your food could be dropped in any number of locations).
At least on my mobile, I get ~100 ms ping to most things. Admittedly I don't use it very often so it's hard to have a real world feel for how frequent things like dropouts are, but that's mostly because data costs a lot. That kind of also ties into developers doing a bad job though (e.g. sending me 10 MB of who knows what when the task (like paying for parking) fundamentally should be doable with a few kB, most of which are the TLS handshake). If they didn't do that, their thing would be instant with 3g speeds. Most CRUD generally just doesn't need a lot of data to actually accomplish the desired task.
Satellite Internet will be slow, but should still be well under a second? I'd still expect that even extreme cases, you wouldn't expect a spinner to complete a single revolution. So it still seems unnecessary.
Anyway, I'm generally on a reliable 300 Mbit/s connection where my pings are more like 20-70 ms, so I suppose you could alter my statement to "if I see a spinner, I interpret it as incompetence".
Then it should give explicit status information like
uploading to server (xx%)...OK
waiting for response...delayed. Check again in 3 minutes.
Not as cool, but at least somewhat informative. Engineers have a responsibility to push back on this kind of thing, because marketing people frequently do not think about failure modes or actually put themselves in the customer's shoes.
> marketing people frequently do not think about failure modes or actually put themselves in the customer's shoes
It’s literally the job of marketing people to put themselves in the customer’s shoes. If engineering isn’t looping in marketing on UX challenges, or if marketing is too focused on top-of-funnel vanity metrics to engage deeply with product usability, things fall through the cracks.
But that’s a company culture issue, not a marketing deficiency.
It should be, but it isn't in my experience. Marketing people care about onboarding and engagement numbers, and are a major driver of dark patterns - everything from popups to moving the 'close dialog' icon to unintuitive places like the bottom left of unasked-for video embeds.
I’m sorry you only worked with terrible, unethical, incompetent marketing people. There are good ones, just like there are bad programmers who do all sorts of terrible and dumb things without creating universal truths about programmers.
I don't think so; I said marketing people frequently do bad stuff, which is not the same as saying they're all bad. I stand by 'frequently', because just look at how much terrible adware, clickbait, spam etc there is on the web. It's a Gresham's law-type situation.
Of course marketing people do a valuable job in terms of figuring out how to sell things and minimize the gap between producers and customers. But - just like engineers - there are lots of cynical and amoral people who work in that industry who make things worse for everyone else. By contrast, I can't think of any society that is suffering because they don't have enough advertising.
Effective marketing (not just comms, but real positioning and messaging) is why people can find the right products and services, why small businesses can compete, and why entire industries grow. It's unequivocally a good.
If anything, societies suffer when good marketing is absent—because that’s when bad actors fill the void with misinformation, hype, and scammy tactics.
Effective marketing (not just comms, but real positioning and messaging) is why people can find the right products and services
If that's your metric, I can confirm the GP's statement, at least when it comes to online marketing people. Increasingly, I can not find the right products and services online.
> If anything, societies suffer when good marketing is absent—because that’s when bad actors fill the void with misinformation, hype, and scammy tactics.
Except, marketing too is a market for lemons. Scammy marketing outcompetes good marketing. Simple as that.
Scammy marketing can sometimes be effective in the short term, but the problem with it it’s inherently self-limiting.
Deceptive brands burn their audiences, lose customer trust, and either get regulated out of existence or collapse under their own churn rates. Meanwhile, companies that invest in clear, honest positioning, strong customer relationships, and long-term brand value consistently outperform in the long run. Apple, Patagonia, and Tesla aren’t winning because they spam pop-ups.
If marketing were purely a race to the bottom, all successful brands would look like clickbait farms. They don’t.
Where I used to live, in NY (not NYC, but close to _a_ major city), I had to go out onto my front porch to use my cell phone. It wasn't a great signal out there, but it was better than the _no_ signal inside my apartment.
Some things in the real world simply take longer than milliseconds; this is not a failing. I'm working with a system that takes over 10 seconds to get a list of wifi access points, and you bet we throw up a spinner while that's happening.
Now of course if the spinner is merely cosmetic and doesn't represent any actual work going on, that can be a problem especially if the process you're waiting for dies.
I think it's an art, not a science. The alternative to a spinner is to show some sort of error to the user; a connection error or something specific that went wrong that they can report. Sometimes this is useful.
I frequently put spinners just in the individual components that need loading. I tend to use them more for large data loads that will hang around awhile, so I have to do fewer round trip transactions. Loading a list of a customer's last 1000 transactions? I'm going to bring on all that data at once, not keep calling the server as you try to scroll through it.
I want user actions to have an INSTANT consequence, not 150ms latency. So even if not a spinner, that button needs to gray out and something should affirm that they tapped it.
Also, spinners are very useful for me in tracking down bugs. When a few customers report stuck spinners in the same day, I can almost immediately determine if some particular action is failing or whether it's a server issue. Even better, they can send screenshots helping me isolate the problem. If no stuck spinner and the app just freezes, they reload it and forget what exactly they did to trigger an error. And endpoints do go down, nothing has 100% uptime. I want to FEEL how long a call is taking on a heavy operation on a busy day.
Nah. We have a spinner, but I also have a timeout handler.
The reason is that the app's backend (and many of the servers on which it depends) can be hosted on the lowest-tier-dogshit-shared-hosting plan. I would love to have a better backend server, but we are a nonprofit, and can't afford better. This app would be a lot faster, with a more robust backend.
But error handling/reporting is a true art, and should never be an afterthought. In my experience, I need to start thinking about error management, as soon as I start planning.
In my experience, the best error handling is to not have errors, and, quite often, good UX is the answer to that. If the user doesn't do something that might cause agita, then they don't get an error.
> I developed the opinion that putting a spinner into your site at all is a sign of incompetence
This so much. If your site is so slow that it can load what is usually a video file (non-SVG animated graphics) before it can load the text on the page, then you have failed at making a website
Looking at Discourse® here, and iirc Google AMP did something similar except it was a blank page for 8 seconds (until it hit a timeout) if you blocked their tracking
Not sure if it counts as CRUD but, when downloading files, it can take a while to prepare the files. If that while is long enough the user may thing something isn't happening, and a "I'm working on it" signal is not unreasonable.
I used to work with a web developer in state govt who purposely coded a couple seconds delay before data was displayed so that the spinner would always show. He was actually one of the best developers on the team ironically.
150 ms is really bad... in mid 90s, 50 was considered the upper limit before some "busy" indicator was to be shown... these days, I'd consider 20ms to the limit of "good".