Hacker News new | ask | show | jobs
by pmoriarty 2036 days ago
Lying progress bars are one of those ubiquitous anti-features which make me suspect the people who write the apps that have it or who decide what features they are to have never actually use their own software, or they'd realize in a heartbeat how incredibly annoying and frustrating lying progress bars are.

I'd love to hear an HN reader who is brave enough to own up to implementing one of these explain the rationale behind them.

9 comments

Well... story time. I had to implement a lying progress bar at the behest of my client. We could not reliably predict much...network speed, file size, moon phases, sock colour, etc would change things all the time. The client wanted to show the customer that "things were happening"... so we made the bar always move. The logic was that once it hit 90% or more, customers seemed to be invested and would wait forever. And yes, we tracked the abandonment percentage against progress bar percentage.
What's wrong with using something like a spinner in that case though? The big issue with a lying progress bar is that it not only lies when things are happening, it also lies when things are broken, possibly wasting a lot of your users' time.
The goal isn't to save the user time. It's to maximize user conversion rate.
You mean abandonment? Most progress bars are shown when I'm already using your application.
Our most important users (read: $$$) were also the most sophisticated. They also appeared to like numbers... as numbers helped them when they complained back to us that our system sucked. If we took information (as bullshitty as it was) away, they accused us of hiding the truth. As Calvin said to the monsters under his bed... they lie, I lie. Our process was very heavily weighted near the end...so if you made it to 90%...and hung on, it would very likely finish. Again, you need to know your users and play to their strengths/weaknesses and track metrics.
1.) User submits ticket stating "action X is slow"

2.) Project Manager creates dev task "make action X fast"

3.) Too much work to actually make action X fast. Decides to make the user feel like it's going faster.

4.) Deploys fake progress bar to prod. No new tickets.

Its incredible how much faster you can make an app feel by just making the UI respond faster and filling in the data later. As long as something happens instantly its satisfying.
Is this the idea behind that? I can't think of anything I hate more than a web page that loads with absolutely nothing useful, then waits for all the JS to load, then loads content.

I suppose I understand wanting SOMETHING to show up, but could we PLEASE make it be the raw text first?

People love to see progress rather than start to finish speed. Its why getting stuck in traffic is frustrating while riding a bike is not even if you take longer overall.

A blank page for 2 seconds is worse for the average user than a UI template instantly and 2.2 seconds of content filling.

This is why there’s an ever evolving art of progressive/lazy image rendering. There are several techniques that involve populating a blurry or even polygonal version of an image that eventually resolves to the real image. The ultimate payload is larger, and the time to render is greater, but faster UX gratification is more satisfying.

This reminds me of a counterpoint to my top-level comment of how frustrating Apple’s progress bars are: way back in the early OS X days, they did user tests that showed people respond better to longer running progress disclosure than shorter running real progress. So they literally baked a delay into the OS X boot process that would make booting take longer but show a more predictable progress bar.

I've implemented quite a few lying progress bars.

It's impossible to estimate total completion percentage when one part of the operation is CPU-bound, and another part is disk-bound.

(I haven't had to deal with network-bound operations, but I feel for those who do.)

Truth is probably possible, but more work than it's worth, when one part of the operation is O(n) and another part is O(m^2).

If the feature is a week late, it doesn't crash, the answers are right, and the operation completes in a reasonable amount of time, I'm moving on with my life.

Completion percentage doesn't have to be measured in time. If you've completed the CPU-bound operations and are just starting disk-bound operations, it's totally fair to say "50% complete", even if you expect one to take much longer than the other.

Alternatively you could use multiple bars - one showing the number of distinct tasks to complete, and the other showing the estimated time progression of the current task. Ideally chuck an expandible debug log underneath it. You probably want to be implementing a debug log while developing to test the thing anyway, just leave it in there! A lot of installers use this kind of progress bar and I've always found them to be the most user-friendly.

Made one for an internal feature using an overly simple algorithm (% of tasks completed). I was the only one using the tool so I understood the tradeoffs of the progress bar. After a while this tool made it into wider use, but the progress bar remained.
Such a bar is fine imo, especially considering the ratio of effort to return, and much preferable to a spinner. Even if the relative size of various tasks is totally random and disproportionate, at least when the bar fills up, even a pixel, you know forward progress is still being made. The spinner will just spin forever, whether it is deadlocked or not.
Conveying progress in a lot of cases is difficult. Sometimes you have two sets of tasks where the first set determines how much is done in the second. That means you can't accurately predict the overall length of time required to finish everything.

You could split up the overall progress into two parts, 50% of the bar each. The first part might take a while to finish and when you get to 50% you determine how much is left in the second half, and if it's quick, you immediately jump to 100%. On the other hand, if the second half takes really long, now you're sitting there waiting what seems like an eternity to do the second half.

With some clever design, you could have a smarter progress bar system where each task is weighted and adding it to the overall progress re-computes how long everything is, but now you have a scenario where the progress bar could shrink as you get more accurate about the work ahead.

If the time to complete a task is short enough, a lot of these tricks for more accuracy just aren't worth it, and often require fundamentally changing the architecture of your underlying processes, making it more work than it's worth. Hence, you end up with funny things like finishing at 75%. Though, to be fair, they should at least jump to 100% before finishing. I think that's a common bug that comes up, not letting the full bar show first before dismissing.

I wrote a progress bar for an app where it wait time ranges from 5 to 20 seconds, 20-80th percentile for each different function had a range of like 8 seconds--it doing fancy stuff with Selenium. :)

I mocked it up in Figma, I didn't display any numbers, only a cute lil line. Then built it with React Native, super easy and quick, it looked & felt great to me.

So for the actual estimate, what I did was store how long it took to run the task for my users, and then select the 95th percentile from actual runs to get an estimate. Then when they loaded the app, I would send over the estimates (along with their account info and what not). I figured if it ended sooner than what it was projecting, the user would be happy, or at least I was.

I used my own app, and kept tweaking it until it felt right, and it felt really good. YMMV chef's kiss

I suspect fake progress bars do pretty well in a/b testing for page abandons, versus nothing at all. Especially if they show more "done" than not. I don't like it myself, but perhaps it's comforting to those that don't know better.
Can confirm, they work great for users. We had a system where some old things were traditional POST+redirect and the rest was all React with progress bars, disabling buttons when submitting, etc. Users demanded we make everything use progress bars because it's "faster". Our p95 DOM render was 400ms so it wasn't "slow" to begin with. I'm confident it really was the progress bar.
> Our p95 DOM render was 400ms so it wasn't "slow" to begin with.

Not sure why exactly you put quotation marks there, but 400ms is incredibly slow, at least relative to human perception and what computers should be able to do. Consider what AAA games can render in 16ms.

Would love to see a web app you've built that does a HTTPS GET round-trip plus browser render in 16ms.
I didn’t implement one but a former employer did, and [consults my exit agreement] the only thing I can say is they got complaints about long running processes that depended on third party data sources that were so unpredictable that having a colored bar gradually fill up a colorless bar made people stop calling so much, even if it didn’t convey much information.
I made one of these.

We needed a progress bar, but there was no way to estimate progress.