Would you believe me if I told you that you — the speed-and-scale-loving developers you all are — have willingly introduced user-blocking, perceivable latency into your precious applications? If you have any animated effects in your app, then this is very likely to be true! To prove it, I’ll show you how to find, measure, and fix it.
Note to mobile developers: My experience is in web applications, which will be reflected in the examples, libraries, and technologies mentioned below. In the abstract, the same concepts are applicable to mobile platforms, and I hope you can use your judgement and experience to determine the similarities.
Things we know to be true
The following are a list of nearly-universal truths that will act as a guideline for the rest of this article, and hopefully your development.
- Fast is better than slow
- Simple is better than complex
- Simple tends to be fast
- The fastest possible view is blank
Animations are blocking
Certain animated effects block user interaction until they finish showing off. Some examples of such blocking effects include:
- Loading* (spinners, progress bars, buttons)
- Modals (lightbox, confirmations)
- View transitions (carousels, wizards)
*Loading screens aren’t always animations; more on that later.
Perhaps you decide to use a modal to display a billing form. In order to make the opening and closing of a modal less jarring for the user, they often have a built-in animated effect. Let’s say the duration of that animated effect is 400ms. This means that your users must wait a total of 800ms (or 0.8 seconds) just for the animation, every time it’s fired.
It’s not unreasonable to assume that if you had a similar network or computational latency, you’d find a way to optimize it.
Easy to measure, but we don’t
In the modal example described above, the total animation latency was 800ms. Since control over the duration of these animations is provided, it makes it very easy to find and measure this latency. Here are a few common jQuery animation methods that you can grep your codebase for:
If you’re using CSS, you can look for
transition definitions. When else have you ever been able to search your codebase for latency?!
Defaults are too slow
Unfortunately, not specifying a duration sticks you with the library defaults, with typically clock in around 400ms — that’s way too slow! (Library authors: please fix this.) The authors of most modern libraries (CSS and JS) make it relatively easy to override these defaults. If you find yourself shaving yaks in order to make these changes, you might want to shop elsewhere.
My go-to duration is 100ms, but anything longer than 150ms begins to feel sluggish. To demonstrate the point, I’ve put together a quick example using Bootstrap 2 modals.
Not all bad
Much like alcohol, animations aren’t all bad when they’re used responsibly. Fast and simple applications aren’t always pretty and animations can add a little bit of “polish.”
Network-dependent operations can make use of well-timed animations to help the application feel more responsive. For example, a mission-critical network request that typically takes 100ms to complete might pair well with a 150ms animation. This will allow you to maintain that level of polish and keep your application feeling super snappy!
Alternatives to loading screens
Loading screens and spinners are often used to tell the user that the app is doing stuff, but it’s like being put on hold. That animation you chose might be cute for a second, but it’s cuteness will wear off quickly, especially if the user gets stuck.
For slow network requests or tasks which might not be mission-critical (uploading images comes to mind), try deferring the request to a background task and notifying the user when it either finishes or fails. This lets your users get back to your application and do other things without driving them crazy staring at your cute animation.
What’s wrong with JS animations?
As previously mentioned, simple is better than complex and that simplicity lends itself to speed. For reference, here’s how big some popular JS libraries are:
- bootstrap.min.js (v2.3.2) = 28.0KB (7.8KB gzipped)
- foundation.min.js (v4.1.6) = 69KB (18KB gzipped)
- jquery-ui.min-js (v1.10.3) = 223KB (59.6KB gzipped)
A portion of the library that your users must download is the mechanism which animates certain elements (an engine, in a very loose sense of the word).
Hold on; before some of you scroll straight down to the comments in order to point out that you don’t have to download the entire library and can use just the bits you need, you know darn well that most folks include the whole shebang because it’s easier and the user probably has it cached already.
If your library of choice is doing anything more than adding or removing a CSS class to the element in order to animate, then it’s too complicated. Complicated is bad, remember? The more code that’s require to animate something, the greater the potential for bugs. Your favorite libraries do have bugs — just go look at the number of open and closed issues on Github, it’s never zero.
Going back to the earlier modal example once more — if the modal breaks because of a bug in the animation, then your users can’t give you their credit card info, which means you can’t get paid. Do you hate getting paid?
Another problem with relying on JS for animations is that it complicates your ability to write unit tests. When unit tests are complicated, they don’t get written. Testing rocks, debugging sucks.
- Progressive enhancement/Graceful degradation: The application still works, even if the browser doesn’t support it the transitions.
- Better code separation: Animated effects are style. Style is for stylesheets, Workflow is for JS.
- Native: Users don’t download an engine to implement the animation, you just add/remove CSS classes. Simple.
- Less network latency
- Less complexity
Thinking of animated effects as a form of latency will help you, the developer, keep your applications fast and your users happy. The tips above should allow you to maintain simple, testable, and logically-separated codebases. Whenever possible, use CSS effects (Effeckt.css looks promising) and avoid JS effects for mission-critical workflow. Keep the duration of all animated effects short (150ms or less) for a snappy feel. As with anything you may read online, take all of my advice with a grain of salt and use your best judgement.