PG Day Us: Animations for Web & Hybrid
Transcript of PG Day Us: Animations for Web & Hybrid
Animations for Web &
Hybrid@alexblom
Isle of Code
whoami
Isle of Code
• Toronto + Houston based development;
• Focused on Ember/Vue/React/Cordova;
• Creators of ember-cordova & corber;
corber.io
• Extension of ember-cordova;
• Supports Ember, Vue, React, Glimmer;
• CLI for framework -> hybrid builds;
• Adds livereload, unified builds, splash/icons, etc;
corber demo
Contents
• What makes a good animation?;
• Profiling / performance;
• 3 examples;
• Additional options (promoting layers, JS
animation API);
What makes a good
animation?
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;
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;
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;
Profiling / Performance
From 0 to rendered
How our content is rendered
• 1: DOM Tree constructed;
• 2: Layout (recursively from the top left);
• highly interdependent;
• expensive;
Layout Styles
width overflow/overflow-y
min-width font-weight
height font-size
min-height text-align
padding line-height
display vertical-align
border white-space
border-width clear
position bottom/top/left/right
float
Reflow
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
How our content is rendered
• 1: DOM Tree constructed;
• 2: Layout (recursively from the top left);
• 3: Paint;
Paint Styles
border-style outline
border-radius outline-color
background outline-width
background-size outline-style
background-image color
background-repeat visibility
background-position text-decoration
box-shadow
Paint Styles
• opacity is a special case;
• If the element has its own layer, this is handled
automagically by lowering the alpha-mask value;
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);
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);
Promoting a Layer
• will-change property, e.g.;
• will-change: auto;
• will-change: scroll;
• will-change: transform;
Prior Layers
Add will-change;
Layers
Layout Thrashing
Layout Thrashing
Profiler Tool
Profiler Tool
Profiler Tool
Profiler Tool
Profiler Tool
Our Scene
https://www.sitepoint.com/playing-with-fire-organic-css3-animation/
Animation 1 -
The worst case
Animation 1
Animation 1
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;
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;
CSS3 Animations
(@keyframe)
https://www.sitepoint.com/playing-with-fire-organic-css3-animation/
CSS3 Animation
• animation-duration;
• animation-delay;
• animation-timing;
• ease, linear, ease-in, ease-out, ease-in-out,
cubic-bezier;
Why don’t we try them
in this case?
But CSS animations
are hard!
Animation API
Animation 2 -
Hardware Accelerated
http://slides.com/ehayman/deck-1#/6
http://slides.com/ehayman/deck-1#/6
Animation 2
Timeline
Profile
• 6248ms to 5420ms on scripting;
• 10588ms to 4818ms rendering;
• 267ms to 1488ms painting;
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;
Animation Frames
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;
animationFrame
animationFrame
Profile
• 5420ms to 2605ms on scripting;
• 4818ms to 5295ms rendering;
• 1488 to1557ms painting;
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;
Still could be better
• Immediate reaction may be to tear down unused
elements;
• Don’t
Demo
Profile
• 2605ms to 1068ms on scripting;
• 5295ms to 2100ms rendering;
• 1557 to 702ms painting;
Intersection Observer API
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
Intersection Observer API
Intersection Observer API
• callback function receives a list of intersections
detected;
Passive Event Listener
Passive Event Listener
• Allows you to indicate preventDefault will not be
used - e.g. eliminates block on scroll
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;
Animations for Web &
Hybrid@alexblom
Isle of Code