8. FPS Target
• 60fps is considered best;
• 1000ms / 60fps = ~16.6ms per frame;
• 60fps is not always achievable!;
• It is better to deliver a consistent frame rate
than a variable one. Consider targeting 30fps;
9. Animation Options
• Declarative: CSS;
• Generally speaking most performant;
• Browser knows what is happening up front -
can save you from yourself;
• Can become complex to write;
10. Animation Options
• Imperative: JS;
• Tell the browser how. Easier to spell out in
code (e.g. bounce);
• Run on the main thread (not great);
• requestAnimationFrame & webAnimationsAPI
can fix performance issues - to be discussed
later;
16. What causes Reflow?
• Resizing the browser window;
• using JavaScript methods involving computed
styles;
• adding or removing elements from the DOM; and
• changing an element's classes.
• https://developers.google.com/speed/articles/reflo
w
17. How our content is rendered
• 1: DOM Tree constructed;
• 2: Layout (recursively from the top left);
• 3: Paint;
19. Paint Styles
• opacity is a special case;
• If the element has its own layer, this is handled
automagically by lowering the alpha-mask value;
20. How our content is rendered
• 1: DOM Tree constructed;
• 2: Layout (recursively from the top left);
• 3: Paint;
• 4: Composite/Layering (default is a single layer);
21. Layers
• Default is a single layer;
• Composed layer more efficient to animate - GPU;
• Pushing every node to it’s own layer is the worst case;
• The most performant is hardware accelerated
properties on composite layers (e.g.
transform/translateX);
• Layers are expensive (width * height * 3);
40. Some of our problems
• Big FPS dip;
• Each animation is triggering a reflow;
• We are not taking advantage of hardware-
accelerated properties;
• We are redrawing at a fixed (but not) rate;
• Will keep running in an unfocused tab;
41. We are redrawing at a fixed
rate
• Sort of:
• interval timing is not guaranteed - if our thread
is busy it will take longer;
• When a tab is inactive the interval will still fire
every ~1s;
56. Profile
• 6248ms to 5420ms on scripting;
• 10588ms to 4818ms rendering;
• 267ms to 1488ms painting;
57. Some of our problems
• Big FPS dip (sort of);
• Each animation is triggering a reflow;
• We are not taking advantage of hardware-
accelerated properties;
• Will keep running in an unfocused tab;
• We are redrawing at a fixed rate;
59. animationFrame
• Supported for major browsers;
• Only draws when:
• the animation will be visible;
• the browser is ready;
• there are no other frames waiting to be drawn;
• Eliminates unnecessary draws & overloaded
callbacks;
65. Profile
• 5420ms to 2605ms on scripting;
• 4818ms to 5295ms rendering;
• 1488 to1557ms painting;
66. Some of our problems
• Big FPS dip;
• Each animation is triggering a reflow;
• We are not taking advantage of hardware-
accelerated properties;
• This will keep running in an unfocused tab;
• We are redrawing at a fixed rate;
67. Still could be better
• Immediate reaction may be to tear down unused
elements;
• Don’t
73. Intersection Observer API
• “The Intersection Observer API provides a way to
asynchronously observe changes in the
intersection of a target element with an ancestor
element or with a top-level document’s.”
• https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
77. Passive Event Listener
• Allows you to indicate preventDefault will not be
used - e.g. eliminates block on scroll
78. My best practices
• Avoiding JS Animation API until better Safari support;
• Pages with smaller animations (e.g. button bounce):
• CSS/Hardware accelerated animations are fine;
• Will generally promote frequent/transitional
animations to their own layer;
• Pages with lots of animations:
• Just use animationFrame;