Progress bars are great when they convey meaningful information... sometimes it's nice to know if you have time to grab a coffee, or actually eat lunch. In my experience (when having to supply said bars) is that they serve primarily to tell the hapless user that things are still happening. In other words, the actual number is not important...what is important is real feedback that things are still happening and it's worth waiting. Or things are b0rked and you should start over. I don't care about a real time or % progress bar...just something that honestly (to OP's point) lets me know that things aren't screwed.
> I don't care about a real time or % progress bar...just something that honestly (to OP's point) let's me know that things aren't screwed.
That's where "marquee" progress bars fit in. Those poor abominations that, like Sisyphus, progress without advancing, because a simple activity indicator wasn't user-friendly enough.
Especially fun in Web UIs where the callback that would remove the spinner will never be called because some error occurred somewhere in between and is only logged in the console where no normal user will ever see it ...
Personally I feel that to be very much a subversion of the »things are still moving, so stuff is still happening« assumption that has been common in normal desktop applications.
My ideal spinner would be a decreasing arch, telling the user how much time remains until their request timeouts and fails. Uses the same space as a spinner, but conveys more information.
Maybe spinners like these need a kind of "dead man's switch", where something needs to keep telling them "yep, still working" every so often, otherwise an error is shown?
Which is a sane pattern if a language has proper destructors (a seemingly non-existent thing in GC-enabled languages, unfortunately).
In C++, you'd stack-allocate an object representing a spinner, that spawns said spinner in its constructor, and deletes it in its destructor. Then the spinner doesn't outlive the processing code, no matter what path execution took to end the processing.
There are similar patterns in GC-enabled languages ("with" idiom). Async does throw a wrench into this a bit, though.
That’s a different pattern than I was trying to illustrate. I was demonstrating unsafely catching/ignoring/hiding errors and asserting health when it’s demonstrably not true
> Especially fun in Web UIs where the callback that would remove the spinner will never be called because some error occurred somewhere in between and is only logged in the console where no normal user will ever see it ...
I know it’s unpopular in these parts but checked exceptions would make this impossible.
> In other words, the actual number is not important...what is important is real feedback that things are still happening and it's worth waiting.
And the inverse is that when progress bars are fake, they tell the user that everything is working even when it's not!
I MitM my SSL traffic. This causes Figma to fail to load documents in the most annoying way possible—it shows a progress bar that never stops moving, but becomes increasingly slow as it nears the end. I suspect the bar is programmed to never increase by more than half the remaining distance, or something like that.
After half an hour, I finally realized something had to be wrong, and I tried whitelisting figma.com in my proxy. The document loaded immediately.
If Figma hadn't lied to me with a fake progress bar, it would have saved so much time...
I recently found out that you can prepend your search with "name:" and windows search will only match against filenames which is the behavior most users expect by default and much faster than whatever nonsense windows explorer search normally does. Example:
It's not just search when the progress bar appears, though. Also when trying to enumerate contents of a folder - e.g. when you're accessing a networked resource, or one that may not be viewable with your privileges. You then get this bullshit progress bar that speeds through the first 3/4, and asymptotically approaches 100%.
VSCode has a progress bar (well a throbber) that shows up when the language server has waited long enough that the UI should show some activity. But for my workflows it only shows up when something has gone wrong. So when I see it, it’s a good indicator to either restart TS server or reload the whole window. Not a great experience or solution!
> the actual number is not important...what is important is real feedback that things are still happening
Absolutely agree, but then, don't make it a percentage progress bar. Make it one of those "amount unknown" bars, or better yet, a spinner or game-like loading screen. Something with movement that tells me things are happening. Don't pretend to know "how done" it is if you don't know.
The web has ruined those feedback widgets for me. Now every time I see one of those spinners I think “oh look, a gif that will keep spinning even if the process I’m waiting on has failed”.
Progress bars are way better then spinners: They communicate an time/duration estimate, at least. Even in the case it is bad, this is always better then just showing a spinner, indicating that some system is doing something. Spinners got omnipresent since the Web 2.0. Nowadays for me they are almost always a sign of lazy programmers with an "that's good enough" paradigm.
Progress bars that lie are seldom better than spinners. I suppose what is needed is an informed spinner. It would have to be visually different than a bog-standard spinner. I have seen many cases where the numbers on the bar were entirely made up...but they seem to keep people happy. The illusion of progress maybe?
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.
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.
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.
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.
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.
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.
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.
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
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 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 also have seen Apple progress bars rigged to 75%, for some unknown reason, but my biggest offender is my DVR phone app.
On connection it shows the last image sent by the camera, and a progress percent. The progress is really a connection timeout, and you can't be sure it connected or not until it reaches 98% and fails.
Imagine if you used the example with YouTube uploads in the context of giving project progress updates to your boss: "
day 1: We're at 10% completion;
day 2: we're at 20% completion;
...
day 10: we're 100% done, deploying tomorrow;
day 11: actually we have to start over from scratch..."
When progress bars are not useful it is because the underlying problem is hard to extrapolate faithfully. If you are doing just a few tasks where each one takes a significant different time to execute, it will be hard to estimate. More often than not, they work fine, IMO. When they don't, it is because for that particular problem it is genuinely hard to do. It isn't programmer's laziness, I think, in most cases.
It would be nice if they were accurate, but with my limited experience making them, I don't expect them to be. I've actually had the fact they are there screw up rendering.
I often see the suggestion to display spin animations instead since estimation is often incredibly difficult if not impossible. I prefer progress bars because even if they aren't accurate, the relative directional growth shows me that something is actually executing. With a spin animation, for all I know, somethings caught in a loop.
This seems a little funny to me, since the purpose of the spinner is so that you know the computer isn't caught in a loop — it's "busy". It's true, though, that the computer could still be stuck even though it updates the spinner. This is a hard problem to solve.
Abusing progress bars are not a good response to this, though. I would rather trust progress bars for what they are meant to show rather than as an indication of true activity. After all, you still can't tell whether the progress bar kept moving, but the process is stuck in a loop.
>This seems a little funny to me, since the purpose of the spinner is so that you know the computer isn't caught in a loop — it's "busy". It's true, though, that the computer could still be stuck even though it updates the spinner. This is a hard problem to solve.
The problem that people might assume the computer is stuck in a loop or at any rate that the animation is not going to stop is related to spinner animations on websites. Since the spinner is not a function of the browser, but is instead something implemented in the individual site's code, then stopping the spinner needs to be also coded for and many sites neglect to write the code for "when error happens stop spinner and tell them that things went wrong".
So over time people exposed to negligent website spinners start to suspect any spinner that takes too long.
That's because spinners used to show that the main thread was still responsive, but these days are used in different contexts where this isn't really something that it applies to anymore.
In the old days of 68K Mac, it could be even worse. The spinning hourglass was often animated during a timer interrupt, while the main application might have died altogether.
A progress bar should not indicate progress over multiple tasks — a segmented progress bar is better, or a series of spinners, or just a single spinner for the whole set. A progress bar should measure exactly one metric, where the total is known.
It reminds me of the old (maybe it still does it, I dunno) windows install progress bars vs ones where multiple things are wrapped into one.
With multiple things wrapped into one, you often end up in situations where 0-99% (or whatever) might happen super fast but that last 1% takes ages, making the progress bar useless as a "something's happening" indicator.
Those old windows installers used two bars: the top one was basically a steps indicator (file N of M, for example) -- just like the single bar for multiple tasks. But the second bar was a per-file bar. So if step 99 took longer, you had a second bar showing you that steps/files progress.
Yeah, I think I remember those! If it were me, I would turn the segmented bar into a checklist, since you can add a description and I think it looks nicer. But the approach was a good one imo.
Sure, that top bar is a "steps completed" bar, so something other than a normal progress bar may be better. A checklist would work, unless space confined. Depends on the number of items. Maybe a segmented bar where it fills one segment for each item. If there are a lot of items, though, just an "X/Y steps completed" may work best: its simple and easy to understand.
I played with the idea of using a singular circular progress bar for composite progress notification. The basic idea was that if you keep the tail chasing the head, and the head always moving clockwise, the progress bar never gives the impression that it "shrinks backwards", it is always forward motion, but in the worst case when the tail catches up with the head (you discover more sub-tasks) it basically becomes a spinner until the tail starts to lag the head again. Tuning the animation parameters for that provided a lot of options to get a good feeling progress bar that reported a heterogeneous source of various tasks, some of which discovered/added while in progress of the overall whole.
Back in Windows 3.11 days, I noticed a patter with installers. Their progress bar would go steadily up for quite a while, and then suddenly spend 3x as long on just one or two percentage points.
It didn't take me long to realize that the progress bar measured bytes written to disk, but when it was seemingly "stuck", it was creating a lot of small files.
Instead of bytes written, what I really cared about is "how done are you?" and that would have been better represented by a function of both number of files created _and_ bytes written. I don't think the weighting of those two had to be very accurate to be a big improvement.
Exactly! The biggest problem with most progress bars is that they tie together multiple unrelated things that aren't even measured in the same way to a single indicator.
If there are multiple independent tasks, give me multiple independent indicators of their state. Multiple instances of the same class of task can of course be grouped, you don't need to list every file copy independently, but a file copy and an external dependency installer shouldn't be two stops on the same progress bar.
Most users don't understand that making an accurate progress bar is incredibly hard, for most tasks. Is not very intuitive, but once you start looking in to it you realize that almost nothing in a computer is deterministic. Task switching, cashes, file system buffers, disk fragmentation, variable clock frequencies, and loads of other factors, make the speed of a computer very hard to estimate.
I do favor progress bars that say things like "you have downloaded 47% of file X", because its a statement of fact, not an estimation of future performance.
Progress Bars are the most user visible insight into The Halting Problem that our entire industry has. In so many cases, if we knew exactly how long things would take to compute we'd have already computed them or we'd have a world bending solution to The Halting Problem that would change everything. It's really hard to describe NP Complete/NP Hard to the average user, and it shouldn't be a surprise that the poor tool that keeps having to do it over and over again in so many places and ways, the lowly progress bar, keeps getting blamed for our industry having failed to solve (and unlikely to ever solve) The Halting Problem.
Progress bars are much better than spinners in many cases though, even if they lie, at least I get a rough estimation how long something is expected to take, and if it gets stuck.
I've found in apple world progress bars seem to lie more ( not that others don't). Worst of all are the progress bars that take forever to get to the end, then, start a new progress bar. Multiple phases with multiple progress bars is pure evil!
Progress bars are just a tool that needs the right material to work on. I realized that when i tried to progress bar-ify a recursive task.
I think it's more sensible to find a UI language that can seamlessly incorporate a progress bar and a dumb spinner with some note on what's going on. Which one is shown/used will depend on the task that is being loaded. Different words for different things.
I think I'd rather just have predetermined steps/milestones. Think about it...what does 71 percent really mean? Would you get excited when it goes it 72? It's just an opaque, useless metric.
If instead I can see something like...step 1/5, downloading package... that's far more meaningful, at least to me.
I agree in that there should be text with the progress bar showing what the progress bar actually measures, e.g. “57 of 285 records processed” or “3:05 (ETA 10:34)”. If you can’t, then it’s a sign that a progress bar is probably not appropriate.
That would work quite well for low-volatility tasks. iOS upgrades is a pretty good example, for one. In PC-land it gets a bit more difficult due to variations in hardware; see video games.
It depends on how large the variance is, which I suppose you could measure first. You could even show the existing distribution (or typical range) within the progress bar.
A somewhat related approach is used by build servers showing a progress bar of the current build base on how long the previous build(s) of the same project took.
Progress bars work best when they are analyzing repetitive tasks analyzed either in series or in parallel without overhead. If I'm doing something 10,000 times, and if there's no overhead on parallelization or finishing steps. I can be reasonably certain that after 7,000 times, 70% of the time has passed and 30% remains. Maybe there's some step by step variability, but chances are it's dominated by the fraction of iterations complete.
Progress bars work worst when they are combining extremely disparate steps. You might need to run 10 functions, but if one takes 0.1 seconds and one takes 45 seconds, it makes little sense for each step to be counted the same atomically or to present each as 10% of a progress bar.
The absolute worst case scenario is when you depend on an external resource about which availability is unknown but highly variable.
The problem with progress bars is that they're ambiguous on many levels.
What does the progress mean? Is it the fraction of work done or an indication of time left?
Progress bars don't necessarily lie - they simply omit useful information. Estimating progress is hard if there's variables involved that are outside the application's control, e.g. network speed or task switches initiated by the OS.
Task-based progress bars suffer from being "jumpy" and terribly inconsistent, because some tasks take longer than others and the progress indication doesn't allow to estimate the remaining the time.
Time-based progress bars are bad, because they are dynamic by nature of factors mentioned earlier, so ETA might suddenly jump from 1:23 min to 58:07 min or just as bad from 15 minutes to 3 seconds.
This is also the reason why "this is how long it took for other users" is not a great solution either: if your particular circumstances (network speed, server load, ...) are vastly different at the time, this would solve nothing and result in the same complaints.
Progress bars are just an estimation and a mixture of tasks left, ETA and a generic activity indicator ("the app didn't crash and still makes progress") might be more informative.
EDIT: for short tasks (e.g. 20 seconds or less), a simple progression of messages like "working on it", "just a moment", "almost there", "finished" might be the best option.
A progress bar is a chart, nothing more, nothing less. And as any data scientist will tell you, charts without labels are bad charts.
A progress bar should measure exactly one dimension, where a total is known, and a label should show what the dimension is. Usually progress bars implicitly measure "time left", but the total isn't known in that case, so progress bars are inapproprate.
For most "loading" scenarios, a spinner is a more appropriate element.
> Usually progress bars implicitly measure "time left", but the total isn't known in that case, so progress bars are inapproprate.
Are you sure about that? I'd argue that most progress bars explicitly measure tasks/work left and it's the user who wrongly correlates this with "time left" in many cases.
Note that the OP didn't complain about time, but about the percentage not going from 0% to 100% for example.
Yeah, you might be right about that. Still, that's not using a progress bar correctly if it's measuring multiple tasks — they should be measured individually, with spinners or a segmented progress bar.
Please just list out a total number of steps and log when each of those steps is completed (with a short message describing what the step is so that we don't end up back on square one with fractional progress bars). If possible make the steps granular enough so that a step can be completed in under a second (so this may be hundreds or thousands of steps depending on the task length). In the case of say "bytes currently downloaded" this becomes essentially a continuous stream of steps (which is a good thing!).
First and foremost what this communicates to users is that the system is doing something useful. This is what frustrates me about spinners. They are functionally indistinguishable from a frozen system, to the point now that users synonymously identify an indefinitely spinning spinner with a frozen system. And progress bars that asymptotically approach completion even when the program is frozen have trained users to be similarly suspicious of progress bars.
Secondarily it offers the same vague assurances as a progress bar about approximately how much time is left. If you see 250 GB out of 500 GB downloaded you'll assume that you're half-way there, similarly if you see 250 steps out of 500 completed. Especially in the case of the latter, there's no guarantee that the total elapsed time is already 50% over, but that's true of progress bars as well.
Finally, if something goes wrong, there's usually a useful error message that can be shown since there's the context of all the previous steps that led up to this error.
I think there's two issues here that are often wrapped up together: 1. what is the status of my task, and 2. did the computer get stuck
If we could be sure the computer wouldn't get stuck (which is just a bug), then progress bars and spinners would be fine. If the task is as granular as you suggest, progress bars would be a great visual indicator, much better than text.
But since computers do get stuck, additional indicators should help with that. A spinner is supposed to show that a process isn't stuck, but those are fallible too. A textual representation ("bytes currently downloaded") sounds like a great addition to a progress bar. I've seen this a lot on linux distro installers, where you can click "details" below the progress bar to see the console output.
I'm so sick and tired of seeing spinners that keep spinning, even after the process failed; this is an epidemic in web apps, where failures are often a bit too graceful and application state is silently corrupted.
About 15 years ago a coworker had a spinner that was an animated gif, When I see people doing font awesome spinners it reminds me of that gif and I get just as angry.
> But since computers do get stuck, additional indicators should help with that.
They need to be trustworthy. For that, they need to be wired directly into the process doing the work. So no spinner gifs that are animated by the browser/renderer, and can spin forever even if your application dies. It needs to be something where any visual change is directly related to the operations you're monitoring.
That's why a list with textual descriptions of step is a great idea - it's literally too much work to implement it in a way other than the actual completion of a step displaying/ticking off a corresponding label. So seeing that, I'd know the software isn't lying to me.
How about a progress bar that you can expand into a more itemized status presentation-- either a list of tasks or even a log of exactly the last task started and when it was done.
Itemizing individual steps allows users to reason about their performance characteristics, if well explained. These might cause jerkiness in the overall bar.
If I had a progress bar stuck at 27%, it would be valuable to click a little "view more" link and see "11:34 AM: begin downloading file 27/100: foo.tgz (62.3Gb)" I'd be more willing to expect to wait on it advancing than if it was a 30k file.
I'm going to be a radical and say it really doesn't matter any more. We've just gotten used to them not being accurate.
If your progress bar implementation is getting things wrong, you can probably just replace it with a loading spinner and call it a day. That's a vastly easier solution than making the progress bar accurate.
The progress bar for software updates and file transfers on macOS are infuriating. They’re decidedly unhelpful, and more often drastically wrong than anything I could imagine implementing myself. So wrong that it seems some significant improvements would be really low hanging fruit, if they cared to try:
- Doing anything with many smaller files will perform worse than fewer, larger files. Factor in a size/quantity multiplier/ratio on initial estimate. For APFS, I think the information needed should be available from init. For other file systems, this information should be gathered in a background process and feed the estimate as it accumulates.
- Revise the estimate more frequently, but not so frequently it produces pink noise. Apple’s progress bars notoriously get stuck for long periods, even hours. This isn’t just a bad user experience, it’s actually dangerous. Users frequently interrupt long running processes they perceive to be stalled, even if progress is ongoing but merely hard to observe. Swinging too far in the other direction at least gives an indication that something is happening, but the values become meaningless (I don’t know if this is still the case on Windows but I distinctly remember laughing uncontrollably watching estimates rapidly vacillate between seconds and hours, while overall progress appeared to have a steady pace).
- Revise the estimate based on expectations versus reality. As in, if your predetermined formula says 1000 small file operations take 15 seconds, but a comparable workload takes 30... and vice versa for large file operations... measure that! You don’t need machine learning for this, just a sufficiently proportionate time window to do some basic arithmetic.
- Provide additional observable feedback when these adjustments take place, and when there’s nothing to report other than something is taking a long time to generate more meaningful feedback. This doesn’t have to be ugly or noisy, it can be as simple as expanding the progress bar or messaging that progress is really ongoing even if you have no more information to report.
- Give us nerds a log! Please for the love of all that’s good in the world, let us see the sausage go through the grinder, even if we need to know a magic incantation to conjure it. And supplement it with a heartbeat message during long runs so we also don’t fall prey to dangerously assuming the process has stalled.
- I know Apple is notoriously minimalist in its UX style (most of the time), but maybe more information is sometimes actually less. As an example, major OS updates often quietly include multiple stages like firmware updates that require a reboot or temporarily disabling the display. These can be very alarming to users who don’t know what happened! Again, not just bad UX, it can be misleading and users may assume they’ve experienced failure or even an update loop that won’t terminate. A small amount of communication to set expectations could go a long way to alleviate that. A simple list of the overall steps and a bit of warning before a major visual disruption to observable progress would significantly reduce the chaotic list of assumptions users might be imagining.
- Maybe these updates are just too big, and doing too much at once. I mean, I understand that a major version update is going to have bigger subsystem impact, but maybe some of the ancillary stuff can be deferred. As an example, a major version update could get enough of the underlying update in place to get the machine in a usable state, then prioritize user land updates based on demand and run the rest in a background process.
- If you just don’t know, maybe it’s better to just be more vague. Apple popularized the spinner where progress is indeterminate. Use it as a last resort!
I'd thought of making a progress bar library that you'd configure with information like:
- author_uuid: 0xdeadbeef
- download_size: 10GB, domain: example.com
- file_write_size: 10GB
- cpu_time_estimate: 8s
- download_size: 100MB, domain: othersite.com
- file_write_size: 200MB # after decompression
- cpu_time_estimate: 30s
and let it learn over time. My computer can figure out how fast it can download from example.com based on previous transfers. It can figure out how fast my hard drive is based on previous writes. It can figure out how fast its CPU compared to that particular vendor's test system based on previous runs. And if a company like Apple were to deploy this, they could pre-populate the database with very accurate guesses for file write speeds and CPU seconds.
If you had that information, the progress bar could have a pretty solid idea of how long the total progress would take.
You know what I like for progress bars? The mess that is your average build script.
Tell me how many tasks there are to complete, how many you've done, and some rough details of what you're doing (e.g. is it a network request). Don't be shy about commentary ("This may take a while", "If this fails multiple times do X").
These generally contain all of the information that the developer has access to, and rarely am I left having no idea if something's failed, or what to do if I know it's failed.
Now I'm not suggesting that this is good as-is for non-technical users, but it feels wrong-headed keep iterating on a solution everyone hates (progress bars), rather than trying to adapt a solution that (if other people feel the same as me) is quite well-liked in its domain.
You see a sort of adaptation in some progress bars with the "Show details" button, but that generally sanitised variant, with one line per task and no commentary (and often, for some reason, no task count) feels like it misses all the good parts of what it's emulating.
Nix has had a progress indicator for a few years now[0]. It doesn't provide any time estimates but it does show which part of the build it is on (unpack/patch/configure/build/install), how many dependencies it has built or fetched from a binary cache and how many remain. The full build log is accessible with the nix-log command as well, so it's nice from the both a user and dev viewpoint.
For long builds I have stopped watching build logs live altogether and append `; tput bel` to the command to get audible feedback at the end.
For graphical applications, especially on mobile, I wish progress bars got out of the way more. Users ought to be able to continue using an app while a task occurs in a separate thread, and whose progress bar doesn't take up the entire visual field. Many apps, especially on iOS, seem to still be guilty of this.
One tricky thing, though. The few times I saw someone trying to implement the task count, it would sometimes be the case the count couldn't be determined beforehand! So I'd see progress reports like: 1/123 done.... 42/124 done... 45/2616 done... 68/98213 done...
I think scandisk (or whatever the disk scanning utility that runs before Windows boots is called these days) was prone to such ever-growing task counts. I don't know what the right answer here is, except maybe try to split your process into a "planning" part and "execution" part if possible...
> One tricky thing, though. The few times I saw someone trying to implement the task count, it would sometimes be the case the count couldn't be determined beforehand! So I'd see progress reports like: 1/123 done.... 42/124 done... 45/2616 done... 68/98213 done...
SharePoint search does something similar! It doesn't search everything, so it just says "about X items found" based on an estimate. Everytime you click on the next search page, that number gets a little more accurate
Honestly, the example with the incrementing total, while not useful for estimating remaining time, conveys a lot of information. I'd be happy with that for processes that have an unknown number of steps.
> split your process into a "planning" part and "execution" part if possible
Doing the scanning and the processing at the same time may be faster. It should be clear though when the total has been established and when it isn't yet.
After various progressbars on different projects my approach is this:
- Have an array of tasks
- Have a % progressbar
- Each task adds (100/total_tasks)% once completed regardless of how fast it is
Now comes the fun part. There is this single task that takes up the majority of the time amd your progressbar is stuck at 56% percent for too much time compared to the other tasks. You don't have feedback as a user. Is it stuck? Is it still going on?
Now is the time to optimize for use experience!
Why is this task taking so long? Are you loading a huge asset? Break it up, compress it, optimoze it. Are you doing something CPU intensive? Break up your computation over distinct tasks.
This attitude has led me to implement better technological solutions as well as user experiences
Good on you. Most progress bars are about user experience and not so much about accuracy. People just want to know that there's a long sequence of work and that progress is being made.
It's often an illusion and showing too much how the sausage is made makes the user start asking questions about what's happening behind the scenes.
That said, a long task that is prone to failure due to external factors should definitely be conveyed in the progress bar. If a bad network connection is affecting a process from finishing, you obviously want the user to know that so they don't blame the software for being slow. :)
A progress bar is only appropriate to show one metric changing between two known points over time.
- A progress bar should not measure multiple tasks, unless each task is of the same type (e.g. converting a batch of files, _not_ system booting)
- A progress bar should not measure "time left" unless it is literally tied to the value of a timer (i.e. _not_ "time left to download big file")
- A progress bar does not show "busy state" — a spinner does that. A progress bar can stop if e.g. it measures bytes of a file downloaded and the network connection drops; a spinner will still spin.
- A progress bar should include a label to explicitly state what it is measuring (otherwise users will assume it means "time left")
People like to see progress bars because they want to know "progress is being made", but a progress bar is not always appropriate, depending on the situation. Instead, consider using:
- Spinners show activity is happening. Use when there isn't a single metric to report, or the "bounds" of the metric aren't known.
- A checklist can show different tasks completed in sequence. Can be combined with a spinner on the "current" task
- A segmented progress bar can replace a checklist when each task could be represented by a progress bar
Just my opinions, I guess, and obviously we don't live in the world where the above is applied, but it feels good to have it sorted in my own head. Curious what others think of this scheme.
I think duty #1 of a progress bar is just to reliably communicate whether it is frozen or not. In many cases, slow progress is fine as long as it isn't stuck.
Yeah, the main thing I want to know is that the process is still working as expected and not crashed or interrupted. In many cases that's more important than the time value.
I actually don't mind the occasional lying progress bar. I think TurboTax is famous for this, where they just toss in fake progress bars to indicate that they are crunching some numbers, which really just take milliseconds, if that. The goal is just to convey that "heavy work is happening".
I ended up using this strategy recently because I wanted to convey that my app was "doing work on your behalf", so I tossed in a super quick progress bar like TurboTax does and then did a slick transition animation to show the results. It's "unnecessary" in that I could've just showed you the results, but I really wanted to convey that there was a sort of cause-and-effect in the system. Without that little bit of animation, it felt like that would've been lost.
Having some kind of transition to visually indicate a change of state is fine. But that's not what TurboTax does; they have a progress bar that is insultingly superfluous, because there's already a "next" button.
It's worse. They seem to be intentionally slowing things down to make it look like the software is somehow "working harder" because to some people it justifies the high price. A progress bar that takes 5s or more to complete for an operation that actually takes under a second.
Charles Spence at Oxford University has done a lot of work on this. It turns out just changing the colour of the plate impacts peoples perception of food.
Hell, the standard everybody seems to have converged upon is a mendacious progress bar where the user is not told what the percentage refers to (e.g., total install time? Number of files processed? Data left to be copied?). The frontend developer could show changing Matrix glyphs instead and the widget would be functionally equivalent but without giving the user false impressions.[1]
Given that as a standard, it's difficult for me to find more outrage for Turbotax misusing this already mendacious widget.
1: Some smarty pants is going to say that at least the percentage is directional and shifting Matrix glyphs are not. Unfortunately, even that isn't true-- UIs have a long history of multiple sequential progress bars with no indication how many there are in total-- see Office Space. So progress widgets have burned through user trust long ago-- even if I've experienced Windows 10 having a single percentage counter that persists across restarts, perhaps the next update will be the time they break that pattern.
To me there's a big difference between intentionally slowing down the underlying operation (or the ability of the UI to go to the next step anyway) so you can show a longer progress bar, and just having a poorly designed uninformative progress bar on the underlying operation.
Not to you, really? I mean, I guess we can't argue about "how outraged you are", that's up to you.
Do you think those poorly designed progress bars are built to intentionally mislead? It's possible. For what end, do you think? The TurboTax one seems designed to intentionally mislead. Even if they both are, I still prefer one that isn't making me wait artificially longer than the software actually requires though.
When we built a real estate search site that worked on a more "lifestyle search" we had to do something similar. We could return results in about 250ms, but a large portion of beta testers gave feedback that it felt "shallow". Added a 4-5 second animation and loading bar, and people gave better feedback on the actual results, etc. Small sample bias? Maybe. But no one ever complained about the speed in the two years we ran it.
231 comments
[ 5.0 ms ] story [ 223 ms ] threadEdit: typos
That's where "marquee" progress bars fit in. Those poor abominations that, like Sisyphus, progress without advancing, because a simple activity indicator wasn't user-friendly enough.
Personally I feel that to be very much a subversion of the »things are still moving, so stuff is still happening« assumption that has been common in normal desktop applications.
As with so many of the issues in web apps, its not even complex or hard to fix these issues. Its just no one cares enough to schedule time for it.
In C++, you'd stack-allocate an object representing a spinner, that spawns said spinner in its constructor, and deletes it in its destructor. Then the spinner doesn't outlive the processing code, no matter what path execution took to end the processing.
There are similar patterns in GC-enabled languages ("with" idiom). Async does throw a wrench into this a bit, though.
Getting something like a callback for progress would require modifications all the way down the stack, akin to what's needed for fully async code.
I know it’s unpopular in these parts but checked exceptions would make this impossible.
And the inverse is that when progress bars are fake, they tell the user that everything is working even when it's not!
I MitM my SSL traffic. This causes Figma to fail to load documents in the most annoying way possible—it shows a progress bar that never stops moving, but becomes increasingly slow as it nears the end. I suspect the bar is programmed to never increase by more than half the remaining distance, or something like that.
After half an hour, I finally realized something had to be wrong, and I tried whitelisting figma.com in my proxy. The document loaded immediately.
If Figma hadn't lied to me with a fake progress bar, it would have saved so much time...
Absolutely agree, but then, don't make it a percentage progress bar. Make it one of those "amount unknown" bars, or better yet, a spinner or game-like loading screen. Something with movement that tells me things are happening. Don't pretend to know "how done" it is if you don't know.
like the "75% max" example from the post. Does it lie? yes. Can it be useful? very much, it is pretty easy to compensate.
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.
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.
I suppose I understand wanting SOMETHING to show up, but could we PLEASE make it be the raw text first?
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 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.
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.
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.
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.
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
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.
We needed a progress bar, but there was no way to estimate progress.
On connection it shows the last image sent by the camera, and a progress percent. The progress is really a connection timeout, and you can't be sure it connected or not until it reaches 98% and fails.
Abusing progress bars are not a good response to this, though. I would rather trust progress bars for what they are meant to show rather than as an indication of true activity. After all, you still can't tell whether the progress bar kept moving, but the process is stuck in a loop.
The problem that people might assume the computer is stuck in a loop or at any rate that the animation is not going to stop is related to spinner animations on websites. Since the spinner is not a function of the browser, but is instead something implemented in the individual site's code, then stopping the spinner needs to be also coded for and many sites neglect to write the code for "when error happens stop spinner and tell them that things went wrong".
So over time people exposed to negligent website spinners start to suspect any spinner that takes too long.
With multiple things wrapped into one, you often end up in situations where 0-99% (or whatever) might happen super fast but that last 1% takes ages, making the progress bar useless as a "something's happening" indicator.
Those old windows installers used two bars: the top one was basically a steps indicator (file N of M, for example) -- just like the single bar for multiple tasks. But the second bar was a per-file bar. So if step 99 took longer, you had a second bar showing you that steps/files progress.
My demo has unfortunately fallen to web bit rot and needs to be updated, but the code is here to explore: https://github.com/worldmaker/compradprog
It didn't take me long to realize that the progress bar measured bytes written to disk, but when it was seemingly "stuck", it was creating a lot of small files.
Instead of bytes written, what I really cared about is "how done are you?" and that would have been better represented by a function of both number of files created _and_ bytes written. I don't think the weighting of those two had to be very accurate to be a big improvement.
If there are multiple independent tasks, give me multiple independent indicators of their state. Multiple instances of the same class of task can of course be grouped, you don't need to list every file copy independently, but a file copy and an external dependency installer shouldn't be two stops on the same progress bar.
I do favor progress bars that say things like "you have downloaded 47% of file X", because its a statement of fact, not an estimation of future performance.
Progress bars are much better than spinners in many cases though, even if they lie, at least I get a rough estimation how long something is expected to take, and if it gets stuck.
I think it's more sensible to find a UI language that can seamlessly incorporate a progress bar and a dumb spinner with some note on what's going on. Which one is shown/used will depend on the task that is being loaded. Different words for different things.
If instead I can see something like...step 1/5, downloading package... that's far more meaningful, at least to me.
Basically: tell me how long it took other people.
A somewhat related approach is used by build servers showing a progress bar of the current build base on how long the previous build(s) of the same project took.
Progress bars work worst when they are combining extremely disparate steps. You might need to run 10 functions, but if one takes 0.1 seconds and one takes 45 seconds, it makes little sense for each step to be counted the same atomically or to present each as 10% of a progress bar.
The absolute worst case scenario is when you depend on an external resource about which availability is unknown but highly variable.
What does the progress mean? Is it the fraction of work done or an indication of time left?
Progress bars don't necessarily lie - they simply omit useful information. Estimating progress is hard if there's variables involved that are outside the application's control, e.g. network speed or task switches initiated by the OS.
Task-based progress bars suffer from being "jumpy" and terribly inconsistent, because some tasks take longer than others and the progress indication doesn't allow to estimate the remaining the time.
Time-based progress bars are bad, because they are dynamic by nature of factors mentioned earlier, so ETA might suddenly jump from 1:23 min to 58:07 min or just as bad from 15 minutes to 3 seconds.
This is also the reason why "this is how long it took for other users" is not a great solution either: if your particular circumstances (network speed, server load, ...) are vastly different at the time, this would solve nothing and result in the same complaints.
Progress bars are just an estimation and a mixture of tasks left, ETA and a generic activity indicator ("the app didn't crash and still makes progress") might be more informative.
EDIT: for short tasks (e.g. 20 seconds or less), a simple progression of messages like "working on it", "just a moment", "almost there", "finished" might be the best option.
A progress bar should measure exactly one dimension, where a total is known, and a label should show what the dimension is. Usually progress bars implicitly measure "time left", but the total isn't known in that case, so progress bars are inapproprate.
For most "loading" scenarios, a spinner is a more appropriate element.
Are you sure about that? I'd argue that most progress bars explicitly measure tasks/work left and it's the user who wrongly correlates this with "time left" in many cases.
Note that the OP didn't complain about time, but about the percentage not going from 0% to 100% for example.
Please just list out a total number of steps and log when each of those steps is completed (with a short message describing what the step is so that we don't end up back on square one with fractional progress bars). If possible make the steps granular enough so that a step can be completed in under a second (so this may be hundreds or thousands of steps depending on the task length). In the case of say "bytes currently downloaded" this becomes essentially a continuous stream of steps (which is a good thing!).
First and foremost what this communicates to users is that the system is doing something useful. This is what frustrates me about spinners. They are functionally indistinguishable from a frozen system, to the point now that users synonymously identify an indefinitely spinning spinner with a frozen system. And progress bars that asymptotically approach completion even when the program is frozen have trained users to be similarly suspicious of progress bars.
Secondarily it offers the same vague assurances as a progress bar about approximately how much time is left. If you see 250 GB out of 500 GB downloaded you'll assume that you're half-way there, similarly if you see 250 steps out of 500 completed. Especially in the case of the latter, there's no guarantee that the total elapsed time is already 50% over, but that's true of progress bars as well.
Finally, if something goes wrong, there's usually a useful error message that can be shown since there's the context of all the previous steps that led up to this error.
If we could be sure the computer wouldn't get stuck (which is just a bug), then progress bars and spinners would be fine. If the task is as granular as you suggest, progress bars would be a great visual indicator, much better than text.
But since computers do get stuck, additional indicators should help with that. A spinner is supposed to show that a process isn't stuck, but those are fallible too. A textual representation ("bytes currently downloaded") sounds like a great addition to a progress bar. I've seen this a lot on linux distro installers, where you can click "details" below the progress bar to see the console output.
They need to be trustworthy. For that, they need to be wired directly into the process doing the work. So no spinner gifs that are animated by the browser/renderer, and can spin forever even if your application dies. It needs to be something where any visual change is directly related to the operations you're monitoring.
That's why a list with textual descriptions of step is a great idea - it's literally too much work to implement it in a way other than the actual completion of a step displaying/ticking off a corresponding label. So seeing that, I'd know the software isn't lying to me.
Itemizing individual steps allows users to reason about their performance characteristics, if well explained. These might cause jerkiness in the overall bar.
If I had a progress bar stuck at 27%, it would be valuable to click a little "view more" link and see "11:34 AM: begin downloading file 27/100: foo.tgz (62.3Gb)" I'd be more willing to expect to wait on it advancing than if it was a 30k file.
If your progress bar implementation is getting things wrong, you can probably just replace it with a loading spinner and call it a day. That's a vastly easier solution than making the progress bar accurate.
- Doing anything with many smaller files will perform worse than fewer, larger files. Factor in a size/quantity multiplier/ratio on initial estimate. For APFS, I think the information needed should be available from init. For other file systems, this information should be gathered in a background process and feed the estimate as it accumulates.
- Revise the estimate more frequently, but not so frequently it produces pink noise. Apple’s progress bars notoriously get stuck for long periods, even hours. This isn’t just a bad user experience, it’s actually dangerous. Users frequently interrupt long running processes they perceive to be stalled, even if progress is ongoing but merely hard to observe. Swinging too far in the other direction at least gives an indication that something is happening, but the values become meaningless (I don’t know if this is still the case on Windows but I distinctly remember laughing uncontrollably watching estimates rapidly vacillate between seconds and hours, while overall progress appeared to have a steady pace).
- Revise the estimate based on expectations versus reality. As in, if your predetermined formula says 1000 small file operations take 15 seconds, but a comparable workload takes 30... and vice versa for large file operations... measure that! You don’t need machine learning for this, just a sufficiently proportionate time window to do some basic arithmetic.
- Provide additional observable feedback when these adjustments take place, and when there’s nothing to report other than something is taking a long time to generate more meaningful feedback. This doesn’t have to be ugly or noisy, it can be as simple as expanding the progress bar or messaging that progress is really ongoing even if you have no more information to report.
- Give us nerds a log! Please for the love of all that’s good in the world, let us see the sausage go through the grinder, even if we need to know a magic incantation to conjure it. And supplement it with a heartbeat message during long runs so we also don’t fall prey to dangerously assuming the process has stalled.
- I know Apple is notoriously minimalist in its UX style (most of the time), but maybe more information is sometimes actually less. As an example, major OS updates often quietly include multiple stages like firmware updates that require a reboot or temporarily disabling the display. These can be very alarming to users who don’t know what happened! Again, not just bad UX, it can be misleading and users may assume they’ve experienced failure or even an update loop that won’t terminate. A small amount of communication to set expectations could go a long way to alleviate that. A simple list of the overall steps and a bit of warning before a major visual disruption to observable progress would significantly reduce the chaotic list of assumptions users might be imagining.
- Maybe these updates are just too big, and doing too much at once. I mean, I understand that a major version update is going to have bigger subsystem impact, but maybe some of the ancillary stuff can be deferred. As an example, a major version update could get enough of the underlying update in place to get the machine in a usable state, then prioritize user land updates based on demand and run the rest in a background process.
- If you just don’t know, maybe it’s better to just be more vague. Apple popularized the spinner where progress is indeterminate. Use it as a last resort!
- author_uuid: 0xdeadbeef
- download_size: 10GB, domain: example.com
- file_write_size: 10GB
- cpu_time_estimate: 8s
- download_size: 100MB, domain: othersite.com
- file_write_size: 200MB # after decompression
- cpu_time_estimate: 30s
and let it learn over time. My computer can figure out how fast it can download from example.com based on previous transfers. It can figure out how fast my hard drive is based on previous writes. It can figure out how fast its CPU compared to that particular vendor's test system based on previous runs. And if a company like Apple were to deploy this, they could pre-populate the database with very accurate guesses for file write speeds and CPU seconds.
If you had that information, the progress bar could have a pretty solid idea of how long the total progress would take.
Tell me how many tasks there are to complete, how many you've done, and some rough details of what you're doing (e.g. is it a network request). Don't be shy about commentary ("This may take a while", "If this fails multiple times do X").
These generally contain all of the information that the developer has access to, and rarely am I left having no idea if something's failed, or what to do if I know it's failed.
Now I'm not suggesting that this is good as-is for non-technical users, but it feels wrong-headed keep iterating on a solution everyone hates (progress bars), rather than trying to adapt a solution that (if other people feel the same as me) is quite well-liked in its domain.
You see a sort of adaptation in some progress bars with the "Show details" button, but that generally sanitised variant, with one line per task and no commentary (and often, for some reason, no task count) feels like it misses all the good parts of what it's emulating.
For long builds I have stopped watching build logs live altogether and append `; tput bel` to the command to get audible feedback at the end.
For graphical applications, especially on mobile, I wish progress bars got out of the way more. Users ought to be able to continue using an app while a task occurs in a separate thread, and whose progress bar doesn't take up the entire visual field. Many apps, especially on iOS, seem to still be guilty of this.
[0] The creator shows it off here, to applause: https://youtu.be/XVIKScU7Uf4?t=420
One tricky thing, though. The few times I saw someone trying to implement the task count, it would sometimes be the case the count couldn't be determined beforehand! So I'd see progress reports like: 1/123 done.... 42/124 done... 45/2616 done... 68/98213 done...
I think scandisk (or whatever the disk scanning utility that runs before Windows boots is called these days) was prone to such ever-growing task counts. I don't know what the right answer here is, except maybe try to split your process into a "planning" part and "execution" part if possible...
SharePoint search does something similar! It doesn't search everything, so it just says "about X items found" based on an estimate. Everytime you click on the next search page, that number gets a little more accurate
Doing the scanning and the processing at the same time may be faster. It should be clear though when the total has been established and when it isn't yet.
After various progressbars on different projects my approach is this:
- Have an array of tasks
- Have a % progressbar
- Each task adds (100/total_tasks)% once completed regardless of how fast it is
Now comes the fun part. There is this single task that takes up the majority of the time amd your progressbar is stuck at 56% percent for too much time compared to the other tasks. You don't have feedback as a user. Is it stuck? Is it still going on?
Now is the time to optimize for use experience!
Why is this task taking so long? Are you loading a huge asset? Break it up, compress it, optimoze it. Are you doing something CPU intensive? Break up your computation over distinct tasks.
This attitude has led me to implement better technological solutions as well as user experiences
It's often an illusion and showing too much how the sausage is made makes the user start asking questions about what's happening behind the scenes.
That said, a long task that is prone to failure due to external factors should definitely be conveyed in the progress bar. If a bad network connection is affecting a process from finishing, you obviously want the user to know that so they don't blame the software for being slow. :)
Next you'll be asking programmers to estimate how long they going to take to do something...!
;-)
- A progress bar should not measure multiple tasks, unless each task is of the same type (e.g. converting a batch of files, _not_ system booting)
- A progress bar should not measure "time left" unless it is literally tied to the value of a timer (i.e. _not_ "time left to download big file")
- A progress bar does not show "busy state" — a spinner does that. A progress bar can stop if e.g. it measures bytes of a file downloaded and the network connection drops; a spinner will still spin.
- A progress bar should include a label to explicitly state what it is measuring (otherwise users will assume it means "time left")
People like to see progress bars because they want to know "progress is being made", but a progress bar is not always appropriate, depending on the situation. Instead, consider using:
- Spinners show activity is happening. Use when there isn't a single metric to report, or the "bounds" of the metric aren't known.
- A checklist can show different tasks completed in sequence. Can be combined with a spinner on the "current" task
- A segmented progress bar can replace a checklist when each task could be represented by a progress bar
Just my opinions, I guess, and obviously we don't live in the world where the above is applied, but it feels good to have it sorted in my own head. Curious what others think of this scheme.
I ended up using this strategy recently because I wanted to convey that my app was "doing work on your behalf", so I tossed in a super quick progress bar like TurboTax does and then did a slick transition animation to show the results. It's "unnecessary" in that I could've just showed you the results, but I really wanted to convey that there was a sort of cause-and-effect in the system. Without that little bit of animation, it felt like that would've been lost.
Given that as a standard, it's difficult for me to find more outrage for Turbotax misusing this already mendacious widget.
1: Some smarty pants is going to say that at least the percentage is directional and shifting Matrix glyphs are not. Unfortunately, even that isn't true-- UIs have a long history of multiple sequential progress bars with no indication how many there are in total-- see Office Space. So progress widgets have burned through user trust long ago-- even if I've experienced Windows 10 having a single percentage counter that persists across restarts, perhaps the next update will be the time they break that pattern.
Not to you, really? I mean, I guess we can't argue about "how outraged you are", that's up to you.
Do you think those poorly designed progress bars are built to intentionally mislead? It's possible. For what end, do you think? The TurboTax one seems designed to intentionally mislead. Even if they both are, I still prefer one that isn't making me wait artificially longer than the software actually requires though.