NProgress: slim, site-wide progress bars
ricostacruz.com
ricostacruz.com
"What?" I hear you asking, "Of course it does! It shows how much longer you'll have to wait."
In which case I must inform you that giving the user information is not the most important function of a progress bar. The most important function of a progress bar is Time Travel.
That is to say, subjective time travel. Try this fiddle: http://jsfiddle.net/gUkgX/1/embedded/result/
First, click "No feedback". Wait for it. Feel how long it takes to run. Try not to count the seconds (you wouldn't usually do that on a real website) - just see how it feels. Next, click "Spinner", and then finally try "Progress bar".
Which one felt shortest?
Of course, they are all the same ten seconds. Yet the spinner feels faster than no feedback, and the progress bar feels faster still. Watching that bar fill up makes the time seem to pass faster.
And the progress bar is totally fake. In fact, it doesn't even take 10 seconds to fill. It fills in 9.2 seconds, starts out fast and slows down, and none of this has anything to do with what is really happening, which is that you're waiting for a 10 second timeout to fire.
My point with all of this is that in order for a progress bar to fulfill its duties as a time condenser, I suspect that it needs to be prominent. I get the idea of keeping the indicator out of the way and minimal, but I think this is misguided in this case.
That's also why windows phone has so many 3D transitions between screens. We use longer transitions for heavier load times, because it makes those load times seem faster. The transitions don't have to be prominent though, at least from the studies we did. They just need to be there.
It drives me NUTS, to say the least.
The file copy dialog was never like this.
In fact, the Windows 8 file copy dialog is not only good, but fantastic.
Please could you talk to the IE team about their progress bars explicitly lying to the user? I understand that giving immediate feedback is important as it can greatly increase perceived responsiveness, but that damn thing (on both desktop and Windows Phone 8) can climb to ~80% before even the first byte is received (it might even manage ~80% before the DNS lookup has returned though I've not tested to prove that). Have you every tried explaining to a non-technical user that their phone didn't "get nearly all the way then stopped" when loading a page? They simply don't believe "your web browsing software is lying to you, it didn't actually receive anything" and look at me as if I'm making things up to try hide that I simply don't understand the hinterwebs.
Of course the lie works: people think IE is more efficient than other browsers simply because on slow site and/or with slow connectivity the progress bar seems to initially push up faster than the one in FF/Chrome/other even though the actual page load time is the same.
I'm fine with little white lies to make the user feel more cared for (which is what fast "apparent response times" is all about: people personify technology so if you don't give the impression of immediate response they feel like some concious entity is actively ignoring them) but the IE progress bar takes that to an irritating extreme, to the point where it is detrimental to UX (I sometimes can't tell if the page is just loading slowly or nothing is transferring at all and I'm just going to get the "page not available" error in 20 seconds time).
It irritates me enough that it will be a factor in deciding what I buy when my current smartphone needs to be replaced (much as I like the Lumia 920; this, other Windows Phone annoyances, and comparative inexpensiveness, will make it difficult to justify not switching to Android next time).
It should be the first feature of windows 9. I would upgrade!
http://www.nytimes.com/2012/08/19/opinion/sunday/why-waiting...
In which an airport discovered it was dramatically better to have people walk longer distances to get their luggage, rather than walk a shorter distance to baggage claim and stand around waiting (all things being equal on the actual time for the luggage to be available to pick up). The walking kept them busy / distracted.
The very popular game Skyrim uses a beautiful looking object / model from the game for interstitial loading screens; you can spin the object, zoom in etc, and it makes the load times a lot more tolerable.
On one of my one-off side projects(http://gifmachine.xwl.me/), there's a rather silly example of the importance of loading bars.
In the first version, the design was quite bare. There were a couple of textinputs and a "make gif" button. The way the code happens to work, when you press the "make gif" button the web page would just sit there till you where re-directed to your finished gif.
The first bit of advice I got from anyone was "this is sooo slow, what's happening?" The problem was, I didn't actually have any way to understand how long/what was going on in the backend. So I decided to take the next best approach:
I fake it.
As soon as you click the "make a gif" button, the bar starts loading. However, that bar has no basis in reality. It takes exactly 40 seconds to fill up, no matter what's going on.
However, everyone loves it! All the comments I got said how much better it seemed to make the experience. Even though it's a fake loading bar.
t/(t+n)
With n set to a bit under half the average load time, if generally looks about right, too.
1. Choosing arbitrary time estimate to use as a target.
2. Providing distractions for if the estimate is much too low (show a secondary progress bar or spinner, maybe even misdirect so the primary bar can backtrack without the user noticing)
3. Calibration based on real results. A simple way would be to use linear regression to map the input guesses to real world results. Then the resulting equation should be easily available to plug into a persistence library or LocalStorage, so that you continue to get accurate results moving forward.
However, I had the idea to use a progress bar to achieve the opposite effect: To introduce an artifical waiting time together with a sense of progress (hence, progress bar). This should convey the feeling that the app is working hard to make Your Personal Prediction and since the app appears to be calculating a lot of stuff, the prediction Must Be Totally Accurate.
Surely, the target users are not necessarily sophisticated technical people.
I haven't implemented it but I definitely want to try it out.
We actually had to put in a setTimeout() for 500ms with a loading gif, followed by an scrollTo() to the top of the results just so users would know something actually happened.
But I'd like to see some actual user testing on whether this kind of progress bar does in fact show a typical user how long they have to wait or allows them to 'Time Travel'. In my own (anecdotal) experience, non-technical users are amazingly blind to small details on screen, sometimes even when they are changing/moving.
At one point, we had a call from a user that had been waiting for one of these operations to finish for a long time. We looked into it and realised that some backend process had crashed, so we restarted it and told him he'd have to reload the app. The user wouldn't hear it - it was still working, he could see the gears turning!
Long ago we used to "login" to a site using BasicAuth and the browser defined login box.... it wasn't flexible/pretty enough so we started using <form>s and integrated them into the page.
We had a path-like URL structure that we used to get to our documents, but our documents became more complex and the path-like structure became less human friendly and more like a unique id that should be under the hood.
We had back (and forward) buttons to navigate through our mainly hierarchical sites, but our sites became less linear so we used javascript to jump around.
Our complex non-linear documents became so complex that we didn't want to reload them all at once, so we started fetching parts of the page and needed to build our own progress indicators within the page.
Soon: Very little of the browser chrome will be relevant to the way we use the web.
Looking at a browser like Google Chrome basically all that is left is tabs, forward and back buttons, refresh button, search/url bar, HTTPS indicator, and right hand menu button.
We couldn't get rid of the back and forward buttons because while JavaScript navigation works inside the page, it doesn't work very well to go back from your site to the site that the user came from, because security is designed to prevent you from easily reading history.
Additionally the refresh button couldn't be replaced by an in page control because if the JavaScript in the page has an error and stops working the refresh also stops working, which would make people unable to refresh the page.
I wouldn't trust an HTTPS icon that was powered by JavaScript inside the page so that also has to be part of the chrome.
The only item on that list that could be removed is the right hand menu button. And since that does stuff like print, bookmark, and settings that also doesn't work as part of the webpage itself.
But who knows? Maybe I'm wrong and we'll find a way to strip the browser down even more, but I don't think that will happen until we develop voice, gesture, or thought controlled interface devices that are faster and more efficient than typing into a search bar or clicking a button. Then we can get rid of all the buttons and controls completely. But at that point the entire experience of browsing would be extremely different, not just the browser chrome.
If you need a visual cue that something is loading on your page, throw up some kind of spinner or other animation that doesn't have a fixed beginning and end. Unless you think you know how to accurately measure the time that http request/response cycle is going to take (you don't).
This is totally different. It's explicitly saying that it might be used with pjax or turbolinks. I don't think there's a way to accurately determine progress information for one of these, the best you can do is use historical data and guess. In this case I think using a progress meter is a bad pattern.
For instance, there's no way to monitor the progress of sending an SMS message, yet the iPhone UI displays a progress bar for it. It assumes that SMS's take an average of 4 seconds to send, so the progress bar moves at that rate.
NProgress follows the same idea, and its default behavior operates similarly. Ideally, you should tweak the progress to be more in tune with your average load times (which is what I've done for our 2 apps that use it).
Notice how much longer you seem to wait with the spinner? Watching a progress bar fill up with a definite end feels way faster. I have often used progress bars that have no connection whatsoever with the process they're "measuring".
Here's the technique I've found works well:
1. Estimate the time the operation will usually take. Call that W (it can be a constant, or you can use a heuristic to guess it specifically for the user).
2. Pick a function that asymptotically approaches 1, e.g. the error function. Transform it it so that f(0.75*W) = 0.75.
3. Now for elapsed time t, fill your progress bar to f(t).
The upshot is that the bar will start fast, and never completely fill. And for the first 75% of the estimated time, it will be accurate (as long as your estimate is). After that, it matters less, since it will take a while for the user's brain to adjust to the slower speed.
Wait, what?
It's pretty clear that the human brain is good at simple integration over time to predict where an object will be in the future, or how long it will take to reach a destination. What it doesn't seem to be as adept at is estimating those things when something is changing speed. I would guess that the reason for this is a combination of the math being harder, the results being more noise-sensitive, and it being less crucial in our evolution to anticipate rapidly accelerating or decelerating targets.
So my first premise is that we estimate time-to-destination based on speed, and that we are slow to update the estimate when the object changes speed.
My second premise is that time perception is heavily influenced by expectation. If click something and then nothing happens for a moment, our wait-time expectation is essentially unbounded, since we aren't even reasonably sure that anything is happening.
If you add a spinner, we become more confident that the wait will end, but the time expectation is still high. If the spinner lingers for too long, our only way to update the expectation is something like "I will be waiting for some significant proportion of the amount of time I've been waiting so far". That's not good, because it actually causes your expectations to invert with respect to reality; as time goes on, you feel further from the end, not closer.
So the idea is that a progress bar feels faster because it gives a decreasing expectation of time left. If the progress bar is accurate, then once it has moved half way, you will expect to wait exactly as long as you have already waited.
Now, the trick with the decelerating progress bar is that it lets you beat accurate expectations by causing the user to underestimate how long they will be waiting.
For example, suppose you accurately estimate that it will take 6 seconds. In the first two seconds, the progress bar will fill, about linearly, to 40%. The user will therefore expect the bar to be full after 5 seconds. After 4.5 seconds, it will be 75% full. If the user were to estimate based on there entire time so far, they'd correctly expect to wait another 1.5 seconds. But that doesn't seem to be what happens. Instead, the user continues to expect less. And so on. In the final moments before the progress bar disappears, the user simply doesn't have time to adjust their expectations.
What seems to lend additional credence to this hypothesis is that you can get even better results by adding random slowdowns and speed ups (while maintaining an average fill curve of erf(erf^-1(estimate)*t/estimate)). When the bar passes the 75% mark where it slows down for good, the user still expects another jump. You can even confirm this expectation by filling the bar at the end it disappears, since at expected completion it will only be 87% full.
No it doesn't. I agree they "feel" faster than the no feedback scenario, but I perceive no difference between the spinner and the progress bar in this case.
I suppose that says good things about the bars, though; they really do signal "loading"...
The progress bar provides users with feedback as to the current status of the page they have requested to load, but it doesn't get in users' way and the page loads and renders as assets become available (unlike in SWF where all interaction is halted until the entire site has been downloaded up front).
Brings lots of memories, I used to make flash games in school when I was 15. I always liked those little games. /nostalgia
The Microsoft installation progress bars are the ones I remember as being ridiculous. Often going backwards, showing ridiculous install times, etc.
Sadly down now. :(
I suggest rereading this insightful article from last year when the Pinterest layout was flavor of the month. http://jfornear.co/the-pinterest-layout-will-not-save-you/
Edit:
Readme says it was inspired by Medium and YouTube - http://www.usabilitypost.com/2013/08/19/new-ui-pattern-websi...
It gave me a feeling of nostalgia seeing this.
While negativity might be discouraging and sometimes might cross the line of a constructive discussion, at the same time it gives some food for thoughts. In this particular case, it gave me more to think about rather than 'looks nice'. So did this post https://news.ycombinator.com/item?id=6143604
You can disable this by removing the `cursor: wait` rule in the CSS file.
Also, I'll be documenting the process here: http://developingandstuff.blogspot.fr/2013/08/nprogress-no-j...
As preparation for a talk: https://twitter.com/mparramon/status/369945214494191616
To wit: a customer asked for a tomato with qualities A, B, and C (anyone who thinks that such a conceptually complex interest in tomatoes is unnecessary needs google 'heirloom tomatoes'). I recommended a Black Krim tomato which, to the best of my knowledge, I believed would meet all of her needs.
She happily purchased six Black Krim tomatoes and went along her merry way. I then asked my manager if there was a better recommendation.
He promptly told me that 1) I was diametrically incorrect in my choice for meeting her needs, and 2) it didn't matter, even in the least.
Sure enough, later that week the same customer came back and specifically thanked me for my excellent recommendation.
I've been reading the comments on various progress bar threads here and elsewhere in the past few days, and I think many of those who dismiss this UI pattern are missing the forest for the trees.
It's not about accurately representing the loading of elements in the page. It's not about accurately predicting and displaying when the page will finish loading. It's not about supplanting browser features for the sake of establishing a site-wide or web-wide standard.
---
It's about making the user feel like things that are out of their view and control are working properly.
---
When I look back on my childhood experiences with computers in the 80s and 90s I distinctly remember my litmus test for "is it frozen" was "can I hear those clicky noises from the hard drive".
Those noises told me nothing directly actionable nor did they accurately describe what had been done or what was left to be done. If, hypothetically, I ran an app caught in some bizarre infinite I/O hard drive loop those noises would have been misleading, and I eventually would have given up and hard-rebooted the computer
Spinning wheels generally act consistently; a loading bar such as this juts and pauses without any noticeable pattern. It gives us the impression that something is happening behind the scenes that we can't directly observe. If it acted uniformly we might just as easily believe that a dumb loop was living out its repetition.
Actual representation of reality is not the point. Perception is the point.
I'm sure that popularity could result in a harmful cliche-ification of this UI pattern, but I believe it has its place and its purpose. A browser cannot divine the amount of content that will be loaded on a dynamic site pre-execution.
At this point in time, at least, I don't mind encountering these loading bars. I can't really think of an example that irk me in any way. If I notice an in-site loading bar sticking around for a while there's probably something happening (or not happening) that would have pissed me off whether or not that loading bar were there.
This is why I hate talking to sales people in brick-and-mortar stores. Appearing confident rather than actually being correct is probably good for closing sales and for short-term customer happiness, but it's no good for the longer-term (ie, when you get home and realize you made the wrong choice).
Well, that depends--and that's where my metaphor breaks down. The customers went home satisfied and remained satisfied (at least, that's what their consistent repeat business and smiling faces would suggest).
Tomatoes and website loading times matter to you in the here and now but don't have any lasting effect on your life. That's not the case for making a major purchase.
You can apply the same reasoning to this UI element. Sometimes - most of the time? - the user doesn't really care about the amount of progress made. They just need to know that something is happening. But at other times, they need to know how much time is actually left on the progress. If that's the case, you need to care about more than just perception.
In all seriousness, given that there are a lot of use cases where an app might be fetching external resources without clearly informing the user as to (i) what's going on and (ii) the current progress, I'd wager the benefits of providing some sort of indication would be measurable even if it's rather fast. I don't really see the presence of an indicator, in any case, enabling an app to get away with slow/slower results.
Using these super thin bars as a "dumb" loader seems like it would only confuse your users. It's like using an icon other than the floppy disk to convey saving.
This doesn't suit all usage patterns (like file downloading where you don't know the file size), but I can think of at least a dozen scenarios in which this is perfectly suitable (even if I don't personally love the effect).
A harder approach would be to be super accurate with actual size of response. Content-length on the header won't work because it only refers to that one file. Also, the server won't have any clue which files belong to which web page response. A way around this is to check every request against a session ID. You'll also have to pass back some sort of "request hash" -- GUID for the request so you can match different files from the same request (static files, content, etc).
It would be cooler to see some guys get together and make a de facto standard, and then implement this type of control into extensions for FF/Chrome.
This bar's UI takes all of 20 minutes to make.
b) Awesomely devious! I love the fake loading animations. Dude you are a fucking genius!
c) Did I mention awesome?
Good to see that there's now a License.md file. (I would have called it LICENSE instead, but eh, bikeshedding.)
I whipped it up quickly so I'm sure there's room for improvement. Feel free to post any issues or enhancement ideas on Github.
I liked this idea but I didn't like the dependency on jQuery and I'm into AngularJS at the moment. So I've created a AngularJS Provider for basically the same thing. Check it out if you have time.
I don't like that - feels like the system is going to hang, and it feels more like a drag on my system than a regular progress bar.
That said, I'm not in love with them on YouTube. They always catch my eye for just a moment after they're done loading about halfway, and makes me crazy.
Think of it as a local optimisation before you reach a global one of instant UI.
sorry...
This is a nice implementation of something that we had an exciting discussion about on HN recently: UI pattern observation from UsabilityPost: Website loading bar [1]