Monday, December 26, 2011

Progress bars & load screens

Bad Game Designer, No Twinkie! has a new installment up at Gamasutra. As always it's pretty great! I agree with a lot of the criticisms made. However, there is one in particular that caught my eye:
Giant Internet Explorer's little circle goes 'round and 'round, telling me nothing. Yet the tiny, free xScope browser for my Android phone includes a progress bar that shows me how much of the page has loaded. It's invaluable.

[...]Put in a progress bar that fills up, once, until the load process is complete. It doesn't have to be perfect; if you load 2 files and one of them is 10KB and one is 10MB, but you allocate half the bar to the first one and half the bar to the second, that's tolerable. We don't really care as long as we can see movement.

The "donut" of the spinning progress circle gets a lot of shit. I just feel compelled to mount a brief defense of it, since the justification makes sense to me. If I were designing a loading screen, I wouldn't want to draw ire for making an entirely justifiable decision.

First, let's look at IE vs xScope to understand how a donut and a progress bar serve slightly different uses. Internet Explorer is normally on a desktop machine, whereas xScope is a mobile browser. It's safe to say that in the author's case Internet Explorer is more likely to be hooked up to a high-speed internet connection, while  xScope is most likely on a 3G mobile connection. The differences between the two are important. If IE listed out every single element on a webpage and calculated how long each would load, it would probably spend more time on those calculations than actually acquiring the data through its fat pipe connection. On a mobile device, however, two things are important: You send out a mobile useragent, which often gets you a simplified version of webpages, and you have a laggy, slow, fairly unreliable connection. Less elements + higher chance something will hang = better reason to do the calculations to show what's left in the loading process.

Now let's look at the suggestion to fake progress bars with the naive approach of grouping files into buckets and just showing rough estimates progress. In this example, the two files differ by four [Three? - ed.] orders of magnitude. Let's be unrealistic for a second to illustrate a point and assume that it takes 1 second to load a 10KB file. So, you sit at the loading screen, and after 1 second of watching an empty progress bar it goes up by half. Very nice!

Now, let's take our naive loading algorithm and assume that it is linear with regards to file size. 1 second for a 10KB file means to load a 10MB file would take... Oh.

(1 second / 10 kb) * (1000 kb / 1 mb ) * (10 mb) = 1,000 seconds.

After waiting for 1 second to see the progress bar move, you are now waiting 16 minutes to see it move again, according to our naive algorithm. The point is not "this would take 16 minutes to load", the point is that files can easily differ by orders of magnitude, so tying progress to file size means your progress bar will have gaps with orders of magnitude. An experience with large time gaps calls the conclusion ("we can see movement") into question, since the majority of time the progress bar is not moving.

Furthermore, there is user research  on the subject of progress bars - ever watch something hit 99% complete and sit there for a while? It's annoying. Much more annoying than, say, waiting for something to go from 0% to 1%. If you want to do loading "right", you need a non-trivial algorithm to display this information to the user.

So now we have two pieces of data from our thought experiment. One is that a naive approach to progress bars is ineffective and doesn't always give the user an assurance that their box hasn't crashed. The other is that users prefer certain algorithms to displaying progress. This is becoming a complicated issue! If you look at documentation, even the MSDN page for progress bars is full of caveats about usage.

Sims2: Pets loading screen. Progress bar with caption:
"Scolding Splines for Reticulating" [Source]

The reason for the spinning donut is simple. It doesn't give the user information to guess a time to completion, so the user can't be frustrated by that last 1% on a loading bar or a fake progress bar that has no relationship to actual completion. Progress bars, in the context of a game, don't really provide useful information to the user. Showing files and categories loaded might be interesting to some, but The Sims shows complete nonsense to the user and no one I'm aware of has ever complained that "reticulating splines" or "Dividing by zero" is misleading - so how useful can accurate information be? The user, as No Twinkie! cedes, is only interested in making sure their console hasn't crashed. So what additional benefit does a progress bar provide over a spinning donut?

My point isn't that progress bars are always bad. My point is that for progress bars to be effective, they need to be carefully considered in context and implementation. It's not just a matter of hacking together the first thing you think of. It's possible to implement load bars properly, but it takes time and effort and risks aggravating your load times even further. All that time and effort spent will need to be revisited when assets are added or removed. Why not just show a spinning donut instead? Users are always going to be frustrated by load times. A donut is not "accurate", but your loading bar isn't going to be accurate either. If you're working on a game, wouldn't you like to fix 5 or 6 more bugs instead of hyper-optimizing something for no benefit?

Edited to correct minor typos, including "an assurance that their box has not crashed" and an off by one on the orders of magnitude involved. Oops.


  1. Superb stuff, Zach.  The treatment of the concept of load progress communication in the article you linked is strangely reductive, and I'm glad you took the time to refine the discussion.  I'd go so far as to say his deployment of the phrase "meaningless loading progress bar" simply shows an unfortunately broad misunderstanding of the concept of "meaning".  I also remain unconvinced that it is, as he writes, "perfectly trivial to do right."  

    As the world plays through Skyrim, your words ring true: Users are always going to be frustrated by load times.  I've thought about it myself while running around in the virtual snow: Are the frequent loads frustrating because there is no progress bar?  No, the frequent loads are frustrating simply because they exist.  Spending time designing graphics to lie about how fun it is to wait seems specious at best.

    For my own part, I say that any argument that associates the progress bar with some possible formulation of truth is doomed to failure.  I've said it for years: the progress bar is the procedural equivalent of creative writing.  At best, there's no way to know how much is true at any given moment.  At worst, the program is just having you on.  Suddenly the idea of a program telling you anything about its present load state seems more than a little absurd.

    So yeah, the spinning progress circle actually makes a lot of sense.  Instead of telling me, "63% to go!," (which, functionally, is guaranteed to be a lie) the spinning progress circle just says, "You're going to have to wait."  I understand designers being frustrated with that communication; but I'm not sure that lying to the player is a better solution.  So again, well done!

  2. A feature I like about Google Chrome's spinning circle is that it goes backwards until the browser actually switches over to the new page, at which point it rolls forwards until the page is done loading. It's a great on my slow internet connection because I can click a link a browse another tab I have opened, and I have a nice visual indicator of when the loading process has changed.

  3. yeah, that's a really good way to convey useful information (looking for server vs page actually loading) that's conveyed quickly, visually, and subtly - it doesn't wash out the top of my screen by using neon colors to illustrate a point, but it's there if i want it. 

  4. yeah even if you sit there with a stopwatch and can guarantee it always takes exactly 60 seconds to load - what if the underlying code changes? what architecture are you measuring on, because it will be different from xbox to PS3 and let's not even get into the PC variations.  what will happen when it takes slightly longer than you've planned - will you roll over your fake progress bar? will you sit on 100% for a bit and give the user an extremely reasonable cause for alarm?

    And if you come up with an algorithm to hit up every single file in order to determine how many there are and how long it would take to load it would be - using your analogy - akin to stopping after every sentence to count how many lines you have left. 

    Skyrim's loading screen fog is essentially a spinning donut in my mind. It leads into another discussion, one @mrwasteland asked a while ago - would you rather have a loading screen without any fun bits on it, or would you rather have a loading screen with some fun bits on it that took slightly longer to finish loading? That's a hard question and one the discussion about donuts vs fake progress bars largely dodges. 

  5. The argument that, "Desktop browsers are on fast connections and things load so quickly that computing a meaningful progress bar would detract from overall performance" only strengthens the argument for better progress bars when they're actually necessary.

    Start with a naive algorithm 1/n of the bar per element of the page to be loaded/rendered/etc, and if things load quickly then that was good enough. When things start to take longer (weak wifi signal, you just have slow internet, horrendous page where the content takes a long time to render or your example) that's when the browser should fall back and try to update the rest of the progress bar in a more meaningful way.

    Windoze solved this issue with the "twin progress bar" paradigm. One bar that updates 1/n of the way for each of n elements and a second progress bar showing the status of the element currently being worked on. An intuitive user design that shows "We've loaded 95% of elements on the page, and are 17% done with this last slow element" might be another proper way to tackle the problem.

  6. "when they are actually neccessary" - right. so the question is, when is it neccessary?

    MSDN recommends against the dual-progress paradigm these days, but it shows up in Windows file copy. Why? Because in  file copy, the user has two "intents":
    1) the user wants to know how -exactly- close they are to done, because it's their files and they are probably moving something to a backup location or a USB stick or something
    2) the user wants to know what files have already been copied, so if/when the copy fails you can have a general idea of how far you got and if the REALLY important stuff got through

    So going back to web browsers, it's important to keep in mind that the complexity of websites has  blown the eff up over the past few years. "
    One article at TheNextWeb weighed in at over 6 MB and required 342 HTTP requests. 73 different JavaScript scripts alone"
    so what are you, as a casual web surfer, going to do when javascript #23 takes a long time to load? It's not particularly important to you, especially if the content of the site is up already (because, asynchronous loading! ).   If you're a web dev checking your own page, you probably have dev tools to provide this information. So as someone who designs a web browser I'd probably say "fuck it, it doesn't provide useful information, people who need the information already have a plugin for it, and i'd rather do this cheaply and do feature X instead". 

    on a mobile browser (which, by the way, IE on winphone7 has a progress bar) i've noticed it's a bit more all-or-nothing and due to the incredible jigger of 3G it lets you know if your connection is vomiting all over the place