Aerotwist - FLIP Your Animations

Right now you’ll need the Web Animations API polyfill to use the code above, though, but it’s pretty lightweight and does make life a lot easier!

If you want a more “in-production” context for FLIP check out the source for cards on the Chrome Dev Summit site.

There is a window of 100ms after someone interacts with your site where you’re able to do work without them noticing.

It’s absolutely superb for times where you are responding to user input and then animating something in response. So, for example, in the case of Chrome Dev Summit, I was expanding cards that the user tapped on. Often the start and end locations and dimensions of the elements aren’t known, because – say – the site is responsive and things move around. This will help you because it’s explicitly measuring elements and giving you the correct values at runtime.

The reason you can afford to do this relatively expensive precalculation is because there is a window of 100ms after someone interacts with your site where you’re able to do work without them noticing. If you’re inside that window users will feel like the site responded instantly! It’s only when things are moving that you need to maintain 60fps.

Taking advantage of user perception.
Taking advantage of user perception.

We can use that window of time to do all that getBoundingClientRect work (or getComputedStyle if that’s your poison) in JavaScript, and from there we make sure that we’re reducing the animation down to nice-and-fast, compositor-friendly, look-ma-no-paints transform and opacity changes. (Why just those? Check out my Pixels are Expensive post.)

Animations that can be remapped to transform and opacity changes are the perfect fit.

Animations that can be remapped to transform and opacity changes are the perfect fit. If you’re already limiting to those properties in your JS or CSS animations then you’re probably good to go; this technique works best when you’re changing layout properties (like width and height, left and top) and you want to remap them to cheaper properties.

Sometimes you will need to rethink your animations to fit this model, and on many occasions I’ve separated and animated elements individually just so that I can animate them without distortion, and FLIP as much as possible. You may feel like that’s overkill, but to me it’s not, and for two reasons:

  1. People want this. My colleague and friend Paul Kinlan recently ran a survey on what people want from a news app. The most popular answer (which was a surprise to him, at least) wasn’t offline support, sync, notifications, or anything like that. It was smooth navigation. Smooth, like no jank, no stutter, no judder. (/me mutters something about #perfmatters.)
  2. Native app devs do this. Of course this is a sliding scale and subjective, but I’ve heard many times of native developers spending days on end getting the transitions in their apps just right. Those “little touches” are a differentiator and, as we get faster loading sites through Service Worker, we’re going to be in the same boat. People will judge our sites based on how well they feel when they’re running.

There are a couple of things to bear in mind if you FLIP:

  1. Don’t exceed the 100ms window. It’s important to remember that you shouldn’t exceed that window, because your app will appear non-responsive if you do. Keep an eye on it through DevTools to know if you’re busting that budget.
  2. Orchestrate your animations carefully. Imagine, if you will, that you’re running one of these animations all transformy and opacity-y and then you decide to do another, which requires a bunch of precalculation. That’s going to interrupt the animation that’s in flight, which is bad. The key here is to make sure your precalculation work is done in idle or the “response window” I talked about, and that two animations don’t stomp over each other.
  3. Content can get distorted. When you’re working in a scale and transform world some elements can get distorted. As I said above I’ve been known to restructure my markup a little to allow me to FLIP without distortion, but it can end up being quite the wrangle.

I’ve come to love FLIP as a way of thinking about animations, because it’s a good match of JavaScript and CSS. Calculate in JavaScript, but let CSS handle the animations for you. You don’t have to use CSS to do the animations, though, you could just as easily use the Web Animations API or JavaScript itself, whatever’s easiest. The main point is that you’re reducing the per-frame complexity and cost (which normally means transform and opacity) to try and give the user the best possible experience.

I have more to tell you about FLIP and a broader, unified model of performance, but that’s going to be the next blog post or so I’d say!

So, uhh, FLIP on.