Name: The Placebo
Context:
Some long-running processing is occurring in your program. You really have no idea how long this event is going to take, but you want to keep the user as happy as possible while it is running.
Forces:
- Users are happier if they can see that something is happening
- A progress-meter spinning in its 'indeterminate' state will placate the user for at most fifteen seconds, after which they will begin to mistrust it
- Users do not expect progress-bars to progress evenly
- Telling a user exactly what is happening to cause a delay is rarely helpful
Therefore:
Estimate how long your long-running process should take. Add a fudge-factor, just in case. Have a progress-bar that runs more-or-less on that time-table until it reaches around 90%. Unavoidably, if it takes longer than this you will have to stick at 90%, but by then the user probably won't cancel the action until at least twice the time you initially budgeted for the action to take.
Educate your help-desk as to the real meaning of "Well, it goes OK for a few minutes and then freezes when it's almost finished..." but ensure they don't tell the user what's really going on, on pain of death.
If there are identifiable milestones along the way, you can incorporate these milestones into your placebo to make it look more accurate.
Note: Users are used to progress-bars that accelerate and decelerate seemingly at random. It could be that a progress-bar displaying this behaviour is more likely to be believed than one that progresses smoothly.
Examples of Use:
Internet Explorer applies a variant of this pattern during DNS lookup and initial TCP/IP connection (the progress-bar creeps forward from time to time, even though no progress is actually being made). This is in direct (and I believe very deliberate) contrast to Netscape Navigator, which would spin its progress-bar in indeterminate mode until the connection was established.
Most GUI installers seem to implement this pattern as a matter of course.
Actually, from the point of view of both a developer and user of software, "milestones" in the progress bar are quite reasonable. What I really want is often not so much an idea of how much time is left but an assurance that the program is making meaningful progress and isn't just stuck. I may just be a leftover from days when software was significantly less reliable, but there it is.
For longer tasks (I worked on DNA software that had common tasks measured in hours) showing a progress bar (just to indicate *something* was happening) and actually displaying the milestones in text form to the users was appreciated.
earl
I'd say it depends on the field of work that the program belongs in. If it's a program that your average joe would use or loosely speciallized fields such as web developers then yes a progress bar will help the user 'see' that something is happening. However as a Mac OS X developer myself, displaying a progress bar actually slows the task down. So you have to weigh up the cost of loosing speed just to visualize a task. Although nowadays this cost is negligible.
Ben
I like it. In the non-GUI world, you get the same effect on the console when the process writes "." ".." "..." "...." etc. As long as the user see more dots appearing, they are reassured that progress is being made. That could just be an illusion, but that's the way it feels to the user.
As regards the 'dots' idea in the last comment, at least that shows that the program is not hung up (as often happens in OSX, especially with MS products it seems - I wish that CrashReporter could ALSO report the SBOD after a certain period of time - I don't think Word will EVER crash, it'll just put up the damn ball FOREVER!)
Anyway, my (probably naive) viewpoint is that if you don't have a reasonable idea of how long something will take (or have one within about a minute, after disk-access/CPU-speed variables can be taken into consideration), then something needs to be recoded.. Of course, programs and OS's these days are so multi-layayered that this may simply be impossible, and on some things, like MPEG compressions, is rather difficult - it depends too much on the video (one frame may compress in a second - not much movement, another may take 1 minute, or may take 30 seconds before the encoder decides to just put in another key-frame - I don't know how the MPEG spec works..)
But one thing I'd like to see for things in the OSX startup, for instance when it's 'waiting for network initialization' if it would TELL me *what* it is waiting for. Especially if there IS NO NETWORK connnected (or is it waiting for the networking protocol stack to come up - and why does it take THAT so long to initalize?
And it seems like OSX could theoretically use some kind of "adaptive progress bar" - the FIRST few times it runs, it's "jerky" and doesn't run smooth. Then the system learns, in it's particular setup (network, disk speed, CPU and bus speed, other things), how long certain parts of the init process will generally take, and adjust the progress bar's "progress rate" accordingly. But then, maybe that's naive too..
I've often wondered - on Macs that have enough memory (768MB-1.5GB), would the startup time decrease a lot if the system simply at the BEGINNING read a whole bunch of frameworks it KNOWS it'll need (whatever System.B.dylib, CoreGraphics, Quartz, QuartzCore, etc) and a lot of the prefs files it knows will need updating (various network parameter files, etc), and just put them on a RAM disk (yes RAM disks do still exist - poke around in the /etc/rc files on the Tiger install CD). Then it wouldn't have to be continuallly seeking back and forth on the disk to read various frameworks or pieces of frameworks (if some kind of direct memory-disk mapping is in place), and seeking all over to rewrite prefs files (to some free spot or the old spot of the file, then back to the directory to rewrite it's entry, etc). Then at the END, write all the prefs files from the RAM disk to the hard disk. Perhpas periodically dump the contents of the "Prefs section" of the RAM disk to some "reserved" part of the disk (for fast access), so that if the power fails, it can recover.
I also wonder if Darwin could be reworked (this would be a BIG BIG rework) so that accesses to files (actually to individual file sectors) could be "optimized" to reduce head-travel, as is done in RAID-5 I believe. Maybe a bit like treating the 1 hard disk like a RAID-5 array, with thousands of "clients" (the requests from the OS). Some provision would have to be put in for latency on files (DV files CANNOT wait to be written, but other might be able to wait a little while. As I said, this would be a MAJOR rework, perhaps basically a rewrite of Darwin itself. And maybe I'm naive - I haven't taken the OS class in the Computer Science sequence yet here at IU..
Jim Witte
While this covers an interesting and sometimes overlooked topic I strongly disagree with the sentiment in the following paragraph:
"Educate your help-desk as to the real meaning of “Well, it goes OK for a few minutes and then freezes when it’s almost finished…” but ensure they don’t tell the user what’s really going on, on pain of death."
In my experience, the approach of actively deceiving the user in this way is doomed to fail. It undermines the entire idea of trying to accurately reflect what is happening by not giving the user truthful and accurate data (to the best of your ability), they will (rightly) learn to mistrust your software and worse, progress bars in other software too.
I agree that progress bars that progress accurately, rather than simply evenly at a pre-determined speed, are far more likely to be taken seriously and believed by the user. However, users should always have good cause to believe them - i.e. the progress bars should accurately reflect your current best guess at the time remaining for the given task, based on present information (data size, current I/O speed, etc). It should not randomly accelerate and decelerate because your software is so poorly written you are unable even to guess roughly how long the task may take to complete.
I agree with Jim here, I know it's not always possible to guess how long something is going to take, but if you can't even make a reasonable estimate then your simply not trying hard enough at looking for ways to estimate it IMO. I also think Earl took the appropriate approach of breaking the action down in to component stages and displaying a text based information at milestones (along with the progress bar), with a non trivial multi-stage task, this is the approach I would take.
If I was working on a project where I *really* had no idea about how long something was going to take and no useful way to estimate, which would be a rare circumstance, I'd still display genuinely *useful* information, such as as how long I'd been running so far and indicate the current data rate (and perhaps even the 'average' data rate so far).
In such a circumstance you could also give estimates for completion for samples of data (e.g. indicating that X amount of data will take approximately Y minutes) or, if the action has a time out period (e.g. a network transaction with a time out period of say 60 seconds) I'd display a progress bar which lasted at most the maximum length of the time out and until then slowly progressed towards it, ending only when the time was up or the task was actually complete.
Lastly, when doing a a complex multi-stage operation where reflecting the an accurate time at which all the disparate operations involved will be complete is difficult, it's worth considering having multiple progress bars, one for the overall task and one for the specific milestone.
Certainly giving accurate information (with text based descriptions of activity) helps users, support teams and developers enormously in the long run when it comes to debugging inevitable problems.
Then again, adopting the placebic progress bar obscures the case where the process has run off into the weeds and will never end (while the bar keeps growing). Custom progress cursors in the Mac OS (< 10) would occasionally keep spinning when the program stopped responding, since the code running the cursor wasn't interacting with the code whose progress it was representing.
Some good example of giving users useful feedback about the duration of longer tasks:
1) emptying the trash when it has many items in it; first it indicates "preparing to empty..." then "emptying..." with a file count.
2) copying a large file or lots of files from one place/system to another provides a numerical tally of progress.
Placebos ought to be a last resort if milestones or quantifiable progress indicators can't be used. IMHO, I'm not sure in what cases they couldn't be used.
Another good point is that Finder empties the trash or copies files without any progress bar if it happens fast enough. Just seeing it done after a split second is enough, so it might be good practice to have a delay before showing a bar if the task could potentially go very fast sometimes.
It's not a matter of 'poorly written' software -- some of us are writing software that has to interact with surly hardware or the network, and there is no way to predict ahead of time what the other end will do.
Apple uses this pattern in the Airport Admin software during a firmware restart, quite effectively.
If I have a task that takes an indeterminate amount of time, at the very least I simply use a "heartbeat monitor" - some kind of revolving/pulsing/etc. animation that *my* program has to keep alive, *not* some background task/thread/etc. I just check to see if enough time has elapsed for an update within my process that is grinding away, and if so, update the animation. I will also try to supply meaningful text alongside to aid in finding what is taking so long or stalling.
Progress bars make zero sense when you can't determine the end-value. Trying to present them as such will only make users stop trusting them altogether.
Seems like Tiger's latest answer is to provide "guideline bars" instead.
yo