Wednesday, August 25, 2010

What You Can Do With Your Modal Dialogs and Splash Screens (and the Horse They Rode In On)

Every time I'm presented with a splash screen, what I actually see is the app developer giving me the two fingered salute. The only thing more hostile is the use of a modal "loading" dialog: a UI metaphor used exclusively to save developers time at the expense of every single one of their users.
The apps which make me want to do something out of character start with a splash screen before segueing directly into a modal "loading" dialog. It's like they're spitting directly into my face. Why? Why do you hate me so much? I just want to use your app, I don't deserve this kind of hostility. No one does.

The 90s called, they'd like their UI metaphors back

Modal windows have always been a crutch. Windowed operating systems are by nature multithreaded, so to avoid apps "freezing" you execute time consuming tasks on background threads. This introduces complexity as the user can potentially interact with the UI between expected states.

The easiest solution for developers is to stick up a modal window that steals focus from the application and prevents users from interacting with the UI until the app completes the background task.

With great latency comes great responsibility

The ascent of the web as a platform largely eliminated these anachronisms. Page load times have a dramatic influence on how quickly people navigate away from a site. When page load latency is being measured in 10s or 100s of milliseconds, it's not surprising that splash screens and "loading" dialogs have all but disappeared.

The good news is that users have also gotten used to content being loaded dynamically. Most people won't bat an eyelid at a page which loads text first and updates the images afterwards. It's expected behaviour.

Users will use the time it takes getting past your splash screen uninstalling your app

It's ironic that a platform that has even less allowance for delay has seen the reintroduction of the dreaded "loading" dialog. Sadly too many devs have gotten lazy. It's harder to develop a UI that works smoothly and intuitively while data is loading or processing is being done, so many don't bother.

Don't be the lazy guy - "it's hard" isn't a valid excuse. Mobile users are incredibly impatient, phones are used on the move and users constantly switch between applications. To be successful you need to make startups and transitions fast and seamless.
  • Asynchronous tasks. Make sure anything that could take longer than a small fraction of a second happens in a background thread (use ASyncTasks to help). Use a Service to run tasks that should be completed even if the Activity is killed.
  • Branding fail. You want your app to seem an integral part of the device. Every time you show a splash screen you're reminding people that they're using an add-on -- an add-on they can replace with something less annoying.
  • Lazy loading. Loading data takes time, particularly if you need to download it first (particularly over a mobile network). It's important that you have something to show as quickly as possible, so take the browser approach by displaying what you can get quickly.  Follow that up with slower items such as images. Load additional content as required when users start scrolling down your list, taking the same approach of text first, images later.
  • In-place updates. Don't clear all your data every time you pull an update from the server. Update, add, and remove items from your UI as new data becomes available. Same with updating existing layouts with images once they've been downloaded.
  • Pre-fetching. If you've got multiple tabs or even Activities within your app, there's no reason to wait until the user changes their selection to start loading data. Pre-fetch the first page of data so that it's ready when the user switches to it.
  • Save your state. Switching between apps should be seamless and instant. Save all your Activity state so your app can resume instantly.
  • Caching. There's no reason to download the same image multiple times. Likewise, it's often better to show out of date information and update it quickly than showing nothing at all.
  • Background loading. Use Services to perform updates and download data while your app isn't in the foreground. This can extend from small amounts of pre-fetching to regular updates, or complete offline support.
  • Visual "loading" elements. Use visual elements like progress bars to indicate that you're in the process of getting an update.
  • Disable unsupported actions. Some actions within your app might not make sense until all the data is loaded. Rather than block interactivity, disable actions that aren't possible.
To see some good examples of how to present no information (or updating information) without splash screens or loading dialogs check out the Gmail and News & Weather apps. Neither use a splash screen (or loading dialogs), and both begin with no information. Once they have data, updates and changes are integrated into the existing data being displayed.

If you're creating a fully immersive experience you may have good reason to use both splash screens and loading dialogs

There's always an exception. If you're engaging in an immersive experience (like a game or turn-by-turn navigation), you don't want to start until the environment is fully constructed. Developers can't use many of the tricks above like dynamic lazy loading, because users want to enjoy the complete experience right from the start. This is especially true of 3D environments like a FPS or Google Earth that rely on an OpenGL environment.

I remember playing California Games on a friends C64. It was loaded via the tape drive, so if anyone quit the game we'd spend the 15 minutes it took to reload in a diverting game of "beat the moron". While it's important to ensure the environment is fully complete before allowing users to explore it, there are still a few tricks you can use to ensure the wait isn't quite as painful.
  • Cache any downloaded content.
  • Dynamically pre-load as much data as possible during gameplay.
  • Save and cache as much state data as possible to ensure players can resume from where they left off.
  • Try to provide useful information (hints? instructions? cut scenes?) in inter-level "loading" screens or splash screens.
  • Delay the longest pauses as long as possible. I should be able to start the game, change the settings, and navigate to "load saved game" without a significant wait.
In conclusion

For most apps, splash screens and modal loading dialogs now belong in the 1990s with 9600 baud modems and pashminas.  Embrace the now.


  1. Anonymous6:47 p.m. BST

    First off, it seems splash screens are pretty commonplace on iOS applications, and last I checked no one is complaining iOS apps belong in the 1990s. I don't think users view splash screens as harshly as you describe unless they have a particular agenda against them. The reality is people are accustomed to them. (For the record I am against them as well, but that doesn't change reality.)

    Secondly, in my experience splash screens are often a marketing requirement and are NOT due to developer laziness. I work at a mostly-iOS application contract shop (with some Android, thankfully) and most projects I know of the customer wants a splash screen for branding purposes.

    All of which is not to say we should be accepting of splash screens, but don't be so quick to shoot the developer. :-)

  2. Anonymous6:48 p.m. BST

    Gmail does contain Views that have the 'Loading...' String if that email isn't in the cache. Whilst you can certainly go BACK to cancel, how is that different to a Dialog with the same string that you can also cancel?

  3. "First off, it seems splash screens are pretty commonplace on iOS applications, and last I checked no one is complaining iOS apps belong in the 1990s"

    Better check again, Anonymous, I did a blog post recently about how frustrating it is to go from an Android device to an iPhone (particularly older ones) because nearly every single iOS app has a splash screen and, for the most part, games are the only apps that have splash screens. ;)

    I think the key point Reto is making is that the app should not get in the way of the user. If the user loads up your news app which defaults to top news, s/he should not be blocked from switching to US News just because top news is loading. A good example is the market app where you can start the app and have everything still loading but the search button is active. A user shouldn't wait for the featured apps to load if s/he simply wants to jump to a search.

    As far as splash screens for branding, that sounds like a case for Make My Logo Bigger Cream....

  4. Sometimes its necessary to have a splash screen. Just look at what happens when you boot up your Android device...

  5. Google Maps has a modal dialog when searching, so as a developer I'm typically going to do the same thing to try to give a familiar UX. What would you do for a search on a map?

  6. Anonymous1:25 p.m. BST

    "First off, it seems splash screens are pretty commonplace on iOS applications, and last I checked no one is complaining iOS apps belong in the 1990s."

    While the overall experience in iOS apps is very nice, its far from perfect.
    There are a number things in iOS that are very last-century and annoying.

    Splash screen are certainly not a good thing and very 90s-like.
    As a user, I think they just suck. I have recently had a look at an iOS app which does the same as my Android app, and noticed two things:
    1. Visually, the iOS app is way more polished. Since an iOS app is pretty by default, while my app is not (and I did not yet take the extra time to make it so)
    2. The iOs app displays a splash screen and takes too much time to load.
    We are not talking about a game. We are talking about a tool which I use to check when the next bus is arriving. A user expects that to be QUICK. I don't want to wait 10s just to get the app to *open*. In android, my apps starts instantly and is about 1000% quicker.

    Enough bashing about splash screens, lets get to another matter:
    The lack of multitasking and the lack of a proper notification system in iOS (which is fundamental for doing proper multitasking) is also very... I don't know, should I say 60s? 70s? ... its actually very sad.

    I'd love developers to listen to these guidelines and get rid of most unnecessary splash screens and other annoying things.

    Having said that, I think Android is to blame for applications not being as visually polished as most iOs apps. While the framework is very powerful, robust and offers no limits to what you can do, developers need to be able to have pretty apps without having to dig through XMLs.

    You see, while you can actually get a prettier Android app than most iphone apps (since it only depends on you, and you are barely limited by the platform or by "app reviewers"), most people don't take the extra effort of doing so.
    Android apps are not pretty by default. iOS apps are.

    We need an Interface Builder for Android. Android developer tools are great but that is the only one thats clearly missing.

  7. Lots of good ideas... if only google would read them.
    See the market app for example, it reloads the entire page if you tilt the screen... every time, even if the last tilt was 1second ago and no scroll was performed.

    The gmail app downloads emails for the primary account, without letting the user disable it, so you have to keep auto-sync off at all times, to use an alternative email app.

    The navigation program does not let the user select after a search, but just takes the first result.
    If its not right, the user can just write a new search, you cant even edit the last search.

    Thers a lot of poor apps out there, and sadly google has its fair share of them.