Motion lessons · #02

Animation duration: a fast API, a slow app?

Published 2026-10-18

A week of optimisation took the API from 1,298 ms to 337 ms. After the release, users said: "…still slow." The server is fast, so where is the time going? This lesson teaches one thing: how long an animation runs.

Motion lesson #02: Duration (50 s, with sound)

What is actually slow: the animation, not the API

We sent a GET request in Hoppscotch and measured 337 ms. If the response then slides in over 0.60 seconds, people wait 0.337 + 0.60 = 0.94 s before they see the full result. With the same curve at 0.25 seconds the total is 0.59 s. The API did not change by a millisecond; only the animation did.

A: 0.60 s, 0.94 s total wait
B: 0.25 s, 0.59 s total wait

One curve, three durations

The curve is the one from lesson 1 (ease-out, cubic-bezier(.16, 1, .3, 1)); only the seconds change. For a panel this size, 0.60 s drags, 0.30 s feels right, and 0.15 s is so quick it seems to pop in. For panels, 0.25 to 0.3 seconds is usually a good start.

Seconds follow distance

Things in the same response that move different distances don’t need the same duration. The status bar moves up only 16 px, in 0.15 s; the body moves 120 px, in 0.30 s. The further something travels, the more time it gets; a small move given too much time feels sluggish.

Starting points (not rules)

Button feedback
0.1 s
Tooltips, small labels
0.15 s
Dropdown menus
0.2 s
Panels, sidebars
0.25–0.3 s
Page transitions
0.3–0.4 s
Over 0.5 s
needs a reason

These are rules of thumb, in the same range as Material Design’s motion durations and Nielsen Norman Group’s advice to keep UI animation between 100 and 500 ms. The right length still depends on the element’s size, how far it moves and the context.

In CSS

.response {
  opacity: 0;
  transform: translateY(120px);
}
.response.is-shown {
  opacity: 1;
  transform: translateY(0);
  /* the body moves 120 px: 0.30 s */
  transition: transform 0.30s cubic-bezier(.16, 1, .3, 1), opacity 0.30s;
}
.status.is-shown {
  /* the status bar moves 16 px: 0.15 s */
  transition: transform 0.15s cubic-bezier(.16, 1, .3, 1);
}

An unofficial motion design concept demo. The interface is from hoppscotch.io (MIT open source); we have no partnership with Hoppscotch. Hoppscotch’s response has no entrance animation of its own: both A and B are ours. 337 ms was the fastest of six measured requests and depends on the network.

The difference is in those few hundred milliseconds.

Next lesson #01Easing: same 0.3 seconds, the difference is how it stops →

Want your product to move like this?

LaunchFlim’s AI director writes motion design as code: paste a URL and get a launch film or a social ad.

Make one free