1 min lesson
Springs vs easing curves
Make the call on "When would you choose a spring over a fixed-duration easing curve for an interaction?" Name the clue that decides it.
Step 1 of 2
Springs vs easing curveswhy interactive motion feels alive
An easing curve has a fixed duration: it always takes 180ms regardless of how far the element travels. A spring is defined by physics - stiffness, damping, mass - so its duration emerges from the motion and it carries velocity. That is why a dragged panel that you release feels right with a spring and wrong with a tween.
- Easing for discrete state changes: a menu opens, a toast appears. Duration is known, distance is fixed.
- Spring for anything continuous or interruptible: drag-and-release, a value that can be re-targeted mid-flight, gestures that hand velocity to the animation.
- Settle on a small easing vocabulary. A standard ease-out for entrances, a sharper curve for exits and one spring config for interactive motion covers most of a product.
When asked to animate a panel resize, say it out loud: “I won’t animate width - that reflows every frame. I’ll FLIP it: measure before and after, then animate a transform from the delta.” Naming the cheap path before you write a line signals the exact instinct this role is hired for.
Learn more
Full explanation
FLIP: animate layout changes cheaply
FLIP: animate layout changes cheaplyFirst, Last, Invert, Play
FLIP lets you animate a layout change using only compositor properties. You measure the element's First position, apply the Last layout instantly, compute the Invert transform that visually places it back at First, then Play by transitioning that transform to zero.
- 1First. Record the element’s box with
getBoundingClientRect()before the change. - 2Last. Make the DOM change (reorder, resize, reparent) and read the new box.
- 3Invert. Set a
transformthat maps Last back onto First, so it looks unmoved. - 4Play. On the next frame, transition the transform to
none- the browser animates the delta on the GPU.
Learn more
Full explanation
Measuring instead of guessing
Measuring instead of guessingthe performance panel is the source of truth
Open the Performance panel, record an interaction and look for long tasks and a green-bar frame rate that holds at 60. Purple layout bars firing every frame mean layout thrash: you are reading geometry and writing styles in the same loop, forcing synchronous reflow. Batch reads, then writes.
- Dropped frames
- Frames over ~16.7ms - the animation stutters
- Recalculate Style / Layout
- Per-frame purple bars = layout-triggering animation
- Forced reflow warning
- A read after a write in the same tick - batch them
- Long tasks (>50ms)
- Main thread blocked; compositor-only motion survives this
Perceived latency is not actual latency. A 100ms operation with an instant skeleton or optimistic state feels faster than a 60ms operation that shows nothing for 60ms. Measure both the frame rate and the time-to-first-feedback - users feel the second one more.
Learn more
Optional practice
Practice: Springs vs easing curves
QYou need to animate a sidebar panel growing from 240px to 320px wide. What is the frame-cheap approach and why?