feelsfast.fyi
Scenarios

Data export / download generation

Generating a download is one of the few perception scenarios where the work is genuinely long — sometimes minutes — and there is nothing the perception layer can do to compress it. What it can do is keep the user oriented while the work runs, and offer a hand-off when the wait crosses the threshold past which they will leave the tab. A spinner does neither. A determinate progress bar with row-count milestones, contextual engagement copy, and an email-when-ready escape hatch does both.

This scenario lives in the 10 S+ band Miller 1968 Miller 1968 placed past the unit-task limit. Nielsen 1993 Nielsen 1993 drew the 10-second wall — past it, the user's attention is no longer reliably on the task, and a hand-off (background work, notification, email) is the correct register. Myers 1985 Myers 1985 covers the determinate progress bar that does the work up to the wall; Harrison et al. 2010 Harrison et al. 2010 covers the backwards-decelerating animation that buys an extra ~12 % perceived speed-up at no real cost.

Data export / download

Server generates a 5,000-row CSV. Naive: opaque spinner past the 10-second wall. Tuned: row-count milestones, engagement copy, and an email-when-ready hand-off if the wait runs long.

10 S+

Off

Press Run to start

On

Press Run to start

What is happening in the demo

The demo simulates a 5,000-row CSV generation at p50 of 12 seconds (gamma-distributed). Click Generate CSV on either side.

The naive side disables the button, shows a generic Loader2 spinner with "Generating download…" text, waits the full duration, then renders the download link. Past the 10-second wall the spinner is doing nothing — the user has no signal of whether they should keep waiting or come back later. Most will switch tabs and forget they were downloading something.

The tuned side does four things differently. First, a determinate progress bar fills based on row count, polled every 100 ms. The user sees concrete progress against a measurable boundary — "1,847 of 5,000 rows" reads as understood work, not opaque time. Second, the engagement copy below the bar rotates through stages — Compiling rows, Applying filters and sorts, Calculating aggregates, Compressing the export, Finalising — telling the user what the system is doing rather than just that it is busy. Third, past the 10-second engagement threshold, an "Email me when it's ready" hand-off appears, converting the foreground wait into background work. Fourth, completion is an explicit success affordance — checkmark, link to the file, total row count — not just "done."

The engagement copy is doing the same job here that engaging-loading copy does on long-running AI inferences: it interleaves the wait with information that gives the user context for the time they are spending.

What to tune

  1. Pre-action — Generate button echo within ~50 ms; no spinner over the whole surface.
  2. First 1 s — determinate progress bar appears, fed by server-side row count or byte count.
  3. 1 – 10 s — bar fills with backwards-decelerating ribs (Harrison 2010, +11–12 %). Engagement copy below the bar rotates through stages ("Compiling rows", "Applying filters", "Compressing the export").
  4. Past 10 s — "Email me when it's ready" hand-off appears. Foreground progress continues; the email is an escape, not the default.
  5. Completion — explicit success affordance: checkmark, link to the file, total row count. Never silent.

When perceived performance hurts you here

The progress bar lies if it does not reflect actual server-side progress. A bar that animates to 100 % over a fixed 12-second CSS keyframe will sit at 100 % while the server is still compressing the result, then the file will silently appear — the lie has shifted from front-loaded to back-loaded but it is still a lie. Either expose a server-side progress API (rows processed, bytes streamed) or use a mid-stream-honest indicator (an indeterminate animation that becomes determinate once you have a real number).

The other failure mode is shipping the email hand-off as the only affordance. If every download requires an email, you have replaced one wait with two — the wait for the export and the wait to remember to check the email. The hand-off is an escape hatch for the long tail, not the default. Show the foreground progress; let the user opt into the email if they have somewhere else to be.

For exports that genuinely take minutes — billing reports, GDPR data-subject access requests, large analytics extracts — invert the default: schedule the job at submission time, surface the existing-jobs list, and let the user click in to see status. The export becomes a list of artefacts with timestamps, not a single button with a wait.

Accessibility

  1. role="progressbar" plus aria-valuemin / valuemax / valuenow is mandatory while progress is determinate.
  2. aria-label that identifies what is progressing, not just that something is. "Generating CSV, 1,847 of 5,000 rows" beats "Loading."
  3. Polite live region for completion ("Export ready") so screen-reader users register the state change without monitoring the bar.
  4. Visible cancellation for the long tail. The email hand-off is not a cancellation — it is a continuation.
  5. prefers-reduced-motion — the bar's width transition is a property change and stays. Strip any rib animation.

References

References · 4

  1. Miller 1968

    Miller, R. B. (1968). Response time in man-computer conversational transactions. Proceedings of the AFIPS Fall Joint Computer Conference, 33(I), 267–277. The 10 S+ wall the export pushes past — beyond which engagement, not progress, is the perception lever.

  2. Myers 1985

    Myers, B. A. (1985). The importance of percent-done progress indicators for computer-human interfaces. Proceedings of CHI '85, 11–17. ~86 % of participants preferred a determinate progress bar over a blank wait — directly applicable while the row count is the natural progress signal.

  3. Harrison et al. 2010

    Harrison, C., Yeo, Z., & Hudson, S. E. (2010). Faster progress bars: Manipulating perceived duration with visual augmentations. Proceedings of CHI '10, 1545–1548. Backwards-decelerating ribbed progress bars yield ~11–12 % perceived speed-up over plain bars at the same real duration.

  4. Nielsen 1993

    Nielsen, J. (1993). Response Times: The 3 Important Limits. From Usability Engineering, Ch. 5. Morgan Kaufmann. The 10-second wall: past it, the user's attention drifts and a hand-off (notification, email) is the right register.