From 9bbb78c61c679c3ff8a85adf246d60dcb2f9e0b5 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sat, 25 Apr 2026 20:08:08 -0400 Subject: [PATCH 01/11] Add Masking Slowness With Animation pattern Closes #1 Co-Authored-By: Claude Opus 4.7 (1M context) --- src/assets/masking_slowness_thumbnail.svg | 21 ++++++++++ .../masking_slowness_with_animation.md | 42 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/assets/masking_slowness_thumbnail.svg create mode 100644 src/patterns/masking_slowness_with_animation.md diff --git a/src/assets/masking_slowness_thumbnail.svg b/src/assets/masking_slowness_thumbnail.svg new file mode 100644 index 0000000..aa5adf3 --- /dev/null +++ b/src/assets/masking_slowness_thumbnail.svg @@ -0,0 +1,21 @@ + + + + + Loading... + + + + + + + + + + + + + + + Mask the wait with motion + diff --git a/src/patterns/masking_slowness_with_animation.md b/src/patterns/masking_slowness_with_animation.md new file mode 100644 index 0000000..1f6962b --- /dev/null +++ b/src/patterns/masking_slowness_with_animation.md @@ -0,0 +1,42 @@ +--- +layout: article.njk +title: Masking Slowness With Animation +tags: pattern +thumbnail: /assets/masking_slowness_thumbnail.svg +og_image: /assets/speed_patterns_og_image.jpg +order: 4 +--- + +Some delays are unavoidable. Network round-trips, third-party APIs, expensive computations and view transitions all take time that no amount of optimization can fully eliminate. + + + +When you can't make the wait shorter, you can change how it feels. Animated transitions occupy the user's attention during the unavoidable gap, smoothing the seam between two states and reducing the perception of delay. + +## The Problem + +When a user clicks a button or follows a link, they expect immediate feedback. If the next state appears abruptly after a noticeable pause, the experience feels broken: the user is left wondering if the click registered, and may click again or navigate away. + +Even when the underlying technical delay is the same, an experience that snaps from one state to another with no transition feels significantly slower than one that gracefully animates between them. + +## Solution + +Use motion to bridge the moment between user input and the new state. A short, purposeful animation does several things at once: + +- **Acknowledges the action** — the user sees that their input registered. +- **Directs attention** — the eye follows movement, naturally landing on what comes next. +- **Hides the delay** — work happening behind the scenes (data fetch, layout recalculation, asset load) overlaps with the animation rather than appearing after a blank pause. + +For example, if a slide-in transition takes 200ms and your data fetch takes 250ms, the perceived delay is only 50ms — and that 50ms feels much shorter when the user just watched something happen. + +## Guidelines + +- **Keep animations short.** 150–300ms is enough to register without feeling slow on its own. Longer animations defeat the purpose by adding to the perceived wait. +- **Make the motion meaningful.** Animation should reflect the spatial or logical relationship between the old and new state — content sliding from where it was tapped, modals scaling out from a button, lists reordering rather than redrawing. +- **Don't fake progress.** If a real delay extends past the animation, switch to a real progress indicator or skeletal placeholder rather than letting the motion loop awkwardly. +- **Respect user preferences.** Honor `prefers-reduced-motion` for users who experience motion sickness or simply prefer a calmer interface. + +## Related Patterns + +- [Skeletal Designs](/patterns/skeletal_designs/) — for waits long enough that motion alone isn't sufficient. +- [Acknowledge Actions](/patterns/acknowledge_actions/) — for the broader principle of immediate feedback to user input. From 5361c30abcc256707094e25910c2fb326ccac61f Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 12:26:28 -0400 Subject: [PATCH 02/11] Move technical implementation details to the end of the article --- src/patterns/masking_slowness_with_animation.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/patterns/masking_slowness_with_animation.md b/src/patterns/masking_slowness_with_animation.md index 1f6962b..978869b 100644 --- a/src/patterns/masking_slowness_with_animation.md +++ b/src/patterns/masking_slowness_with_animation.md @@ -34,9 +34,16 @@ For example, if a slide-in transition takes 200ms and your data fetch takes 250m - **Keep animations short.** 150–300ms is enough to register without feeling slow on its own. Longer animations defeat the purpose by adding to the perceived wait. - **Make the motion meaningful.** Animation should reflect the spatial or logical relationship between the old and new state — content sliding from where it was tapped, modals scaling out from a button, lists reordering rather than redrawing. - **Don't fake progress.** If a real delay extends past the animation, switch to a real progress indicator or skeletal placeholder rather than letting the motion loop awkwardly. -- **Respect user preferences.** Honor `prefers-reduced-motion` for users who experience motion sickness or simply prefer a calmer interface. +- **Respect user preferences.** Some users find motion uncomfortable or distracting; the system should give them a calmer alternative. ## Related Patterns - [Skeletal Designs](/patterns/skeletal_designs/) — for waits long enough that motion alone isn't sufficient. - [Acknowledge Actions](/patterns/acknowledge_actions/) — for the broader principle of immediate feedback to user input. + +## Technical Implementation + +- **CSS transitions and animations** are usually all that's needed. They run on the compositor, don't block the main thread, and are easy to cancel if the underlying work finishes early. +- **View Transitions API** lets a single state change animate across the whole page (or a region of it), making cross-route or cross-view transitions feel native. +- **Honor `prefers-reduced-motion`** — wrap motion-heavy rules in `@media (prefers-reduced-motion: no-preference)` (or set short, non-translating fallbacks under `prefers-reduced-motion: reduce`) for users who experience motion sickness or simply prefer a calmer interface. +- **Profile on a slow device.** A 200ms transition can stretch to 500ms on low-end hardware if the work animating alongside it is heavy — measure on representative devices, not just the developer's laptop. From 3a1bc602684fd2831e563890600a94e69135c08d Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 12:34:59 -0400 Subject: [PATCH 03/11] Drop trailing periods from list items --- .../masking_slowness_with_animation.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/patterns/masking_slowness_with_animation.md b/src/patterns/masking_slowness_with_animation.md index 978869b..06aa5c1 100644 --- a/src/patterns/masking_slowness_with_animation.md +++ b/src/patterns/masking_slowness_with_animation.md @@ -23,27 +23,27 @@ Even when the underlying technical delay is the same, an experience that snaps f Use motion to bridge the moment between user input and the new state. A short, purposeful animation does several things at once: -- **Acknowledges the action** — the user sees that their input registered. -- **Directs attention** — the eye follows movement, naturally landing on what comes next. -- **Hides the delay** — work happening behind the scenes (data fetch, layout recalculation, asset load) overlaps with the animation rather than appearing after a blank pause. +- **Acknowledges the action** — the user sees that their input registered +- **Directs attention** — the eye follows movement, naturally landing on what comes next +- **Hides the delay** — work happening behind the scenes (data fetch, layout recalculation, asset load) overlaps with the animation rather than appearing after a blank pause For example, if a slide-in transition takes 200ms and your data fetch takes 250ms, the perceived delay is only 50ms — and that 50ms feels much shorter when the user just watched something happen. ## Guidelines -- **Keep animations short.** 150–300ms is enough to register without feeling slow on its own. Longer animations defeat the purpose by adding to the perceived wait. -- **Make the motion meaningful.** Animation should reflect the spatial or logical relationship between the old and new state — content sliding from where it was tapped, modals scaling out from a button, lists reordering rather than redrawing. -- **Don't fake progress.** If a real delay extends past the animation, switch to a real progress indicator or skeletal placeholder rather than letting the motion loop awkwardly. -- **Respect user preferences.** Some users find motion uncomfortable or distracting; the system should give them a calmer alternative. +- **Keep animations short.** 150–300ms is enough to register without feeling slow on its own. Longer animations defeat the purpose by adding to the perceived wait +- **Make the motion meaningful.** Animation should reflect the spatial or logical relationship between the old and new state — content sliding from where it was tapped, modals scaling out from a button, lists reordering rather than redrawing +- **Don't fake progress.** If a real delay extends past the animation, switch to a real progress indicator or skeletal placeholder rather than letting the motion loop awkwardly +- **Respect user preferences.** Some users find motion uncomfortable or distracting; the system should give them a calmer alternative ## Related Patterns -- [Skeletal Designs](/patterns/skeletal_designs/) — for waits long enough that motion alone isn't sufficient. -- [Acknowledge Actions](/patterns/acknowledge_actions/) — for the broader principle of immediate feedback to user input. +- [Skeletal Designs](/patterns/skeletal_designs/) — for waits long enough that motion alone isn't sufficient +- [Acknowledge Actions](/patterns/acknowledge_actions/) — for the broader principle of immediate feedback to user input ## Technical Implementation -- **CSS transitions and animations** are usually all that's needed. They run on the compositor, don't block the main thread, and are easy to cancel if the underlying work finishes early. -- **View Transitions API** lets a single state change animate across the whole page (or a region of it), making cross-route or cross-view transitions feel native. -- **Honor `prefers-reduced-motion`** — wrap motion-heavy rules in `@media (prefers-reduced-motion: no-preference)` (or set short, non-translating fallbacks under `prefers-reduced-motion: reduce`) for users who experience motion sickness or simply prefer a calmer interface. -- **Profile on a slow device.** A 200ms transition can stretch to 500ms on low-end hardware if the work animating alongside it is heavy — measure on representative devices, not just the developer's laptop. +- **CSS transitions and animations** are usually all that's needed. They run on the compositor, don't block the main thread, and are easy to cancel if the underlying work finishes early +- **View Transitions API** lets a single state change animate across the whole page (or a region of it), making cross-route or cross-view transitions feel native +- **Honor `prefers-reduced-motion`** — wrap motion-heavy rules in `@media (prefers-reduced-motion: no-preference)` (or set short, non-translating fallbacks under `prefers-reduced-motion: reduce`) for users who experience motion sickness or simply prefer a calmer interface +- **Profile on a slow device.** A 200ms transition can stretch to 500ms on low-end hardware if the work animating alongside it is heavy — measure on representative devices, not just the developer's laptop From a5e87e0a4136a913e5871bd65e29b5f0f4047a28 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 13:10:44 -0400 Subject: [PATCH 04/11] Redraw thumbnail to follow canonical diagram theme --- src/assets/masking_slowness_thumbnail.svg | 36 +++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/assets/masking_slowness_thumbnail.svg b/src/assets/masking_slowness_thumbnail.svg index aa5adf3..0686641 100644 --- a/src/assets/masking_slowness_thumbnail.svg +++ b/src/assets/masking_slowness_thumbnail.svg @@ -1,21 +1,25 @@ - - - - Loading... + + + + Mask the wait with motion + + + Loading... + abrupt wait - - - - - + + + + - - - - - - + + + + + + + + smooth arrival - Mask the wait with motion From bc36261d1d9934db2a5d63f5f5bcf66e2c6ac602 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 13:14:08 -0400 Subject: [PATCH 05/11] Embed thumbnail illustration in Solution section --- src/patterns/masking_slowness_with_animation.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/patterns/masking_slowness_with_animation.md b/src/patterns/masking_slowness_with_animation.md index 06aa5c1..d05b691 100644 --- a/src/patterns/masking_slowness_with_animation.md +++ b/src/patterns/masking_slowness_with_animation.md @@ -21,6 +21,11 @@ Even when the underlying technical delay is the same, an experience that snaps f ## Solution +
+
Without animation the wait reads as an abrupt pause; a short, purposeful transition turns the same delay into smooth arrival.
+An orange 'Loading…' box on the left and a yellow content panel on the right, connected by a curved blue motion line +
+ Use motion to bridge the moment between user input and the new state. A short, purposeful animation does several things at once: - **Acknowledges the action** — the user sees that their input registered From 368c5d8d7ad28c2dda20cd9293715b70442bb990 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 13:24:05 -0400 Subject: [PATCH 06/11] Move SVG title text to figcaption; description becomes paragraph --- src/assets/masking_slowness_thumbnail.svg | 3 +-- src/patterns/masking_slowness_with_animation.md | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/assets/masking_slowness_thumbnail.svg b/src/assets/masking_slowness_thumbnail.svg index 0686641..d4f6f65 100644 --- a/src/assets/masking_slowness_thumbnail.svg +++ b/src/assets/masking_slowness_thumbnail.svg @@ -1,8 +1,7 @@ - + - Mask the wait with motion Loading... diff --git a/src/patterns/masking_slowness_with_animation.md b/src/patterns/masking_slowness_with_animation.md index d05b691..823fed1 100644 --- a/src/patterns/masking_slowness_with_animation.md +++ b/src/patterns/masking_slowness_with_animation.md @@ -21,8 +21,10 @@ Even when the underlying technical delay is the same, an experience that snaps f ## Solution +Without animation the wait reads as an abrupt pause; a short, purposeful transition turns the same delay into smooth arrival. +
-
Without animation the wait reads as an abrupt pause; a short, purposeful transition turns the same delay into smooth arrival.
+
Mask the wait with motion
An orange 'Loading…' box on the left and a yellow content panel on the right, connected by a curved blue motion line From 83013a0df0632d85af22d111258a3efea3d09c50 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 13:34:53 -0400 Subject: [PATCH 07/11] Move figcaption below the image --- src/patterns/masking_slowness_with_animation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/patterns/masking_slowness_with_animation.md b/src/patterns/masking_slowness_with_animation.md index 823fed1..905948b 100644 --- a/src/patterns/masking_slowness_with_animation.md +++ b/src/patterns/masking_slowness_with_animation.md @@ -24,8 +24,8 @@ Even when the underlying technical delay is the same, an experience that snaps f Without animation the wait reads as an abrupt pause; a short, purposeful transition turns the same delay into smooth arrival.
-
Mask the wait with motion
An orange 'Loading…' box on the left and a yellow content panel on the right, connected by a curved blue motion line +
Mask the wait with motion
Use motion to bridge the moment between user input and the new state. A short, purposeful animation does several things at once: From e70bdd694b22b836b17bd095b235dcfdd0aa3aa3 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 13:49:59 -0400 Subject: [PATCH 08/11] Remove arrowhead from motion lines --- src/assets/masking_slowness_thumbnail.svg | 1 - 1 file changed, 1 deletion(-) diff --git a/src/assets/masking_slowness_thumbnail.svg b/src/assets/masking_slowness_thumbnail.svg index d4f6f65..9828bd7 100644 --- a/src/assets/masking_slowness_thumbnail.svg +++ b/src/assets/masking_slowness_thumbnail.svg @@ -12,7 +12,6 @@ - From 9213a736e08114f689654636c6e63c5dc523fc57 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 14:00:50 -0400 Subject: [PATCH 09/11] Use white-with-border content boxes (drop yellow/orange fills) --- src/assets/masking_slowness_thumbnail.svg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/masking_slowness_thumbnail.svg b/src/assets/masking_slowness_thumbnail.svg index 9828bd7..911c968 100644 --- a/src/assets/masking_slowness_thumbnail.svg +++ b/src/assets/masking_slowness_thumbnail.svg @@ -3,7 +3,7 @@ - + Loading... abrupt wait @@ -13,7 +13,7 @@ - + From de07cc570c64f243a385b58e14e425026f33b1c0 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 20:28:24 -0400 Subject: [PATCH 10/11] Add author and creation date to Masking Slowness With Animation Author taken from the original issue (#1) creator; date is the issue creation date. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/patterns/masking_slowness_with_animation.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/patterns/masking_slowness_with_animation.md b/src/patterns/masking_slowness_with_animation.md index 905948b..e14b22a 100644 --- a/src/patterns/masking_slowness_with_animation.md +++ b/src/patterns/masking_slowness_with_animation.md @@ -5,6 +5,10 @@ tags: pattern thumbnail: /assets/masking_slowness_thumbnail.svg og_image: /assets/speed_patterns_og_image.jpg order: 4 +date: 2017-12-04 +authors: + - name: Sergey Chernyshev + url: https://www.sergeychernyshev.com/ --- Some delays are unavoidable. Network round-trips, third-party APIs, expensive computations and view transitions all take time that no amount of optimization can fully eliminate. From 18b95928769ea2f1d8c981ea8c0eda5eb1a2d01e Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Sun, 26 Apr 2026 20:41:33 -0400 Subject: [PATCH 11/11] Mark Masking Slowness With Animation as AI-assisted Co-Authored-By: Claude Opus 4.7 (1M context) --- src/patterns/masking_slowness_with_animation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/patterns/masking_slowness_with_animation.md b/src/patterns/masking_slowness_with_animation.md index e14b22a..7f26019 100644 --- a/src/patterns/masking_slowness_with_animation.md +++ b/src/patterns/masking_slowness_with_animation.md @@ -5,6 +5,7 @@ tags: pattern thumbnail: /assets/masking_slowness_thumbnail.svg og_image: /assets/speed_patterns_og_image.jpg order: 4 +ai_assisted: true date: 2017-12-04 authors: - name: Sergey Chernyshev