feelsfast.fyi
Back

Single File Upload

3 min read

The user picks a file and clicks Upload. The bytes have to transfer; there is real wall-clock time the perception layer cannot remove. What the perception layer can do is replace a generic spinner with a determinate progress bar that reflects actual progress, render the file's metadata optimistically, and finish with a clear success affordance.

This scenario is the canonical use case for determinate progress. Myers 1985 Myers 1985 set the floor — ~86 % of participants preferred a percent-done bar over a blank wait. Harrison et al. 2010 Harrison et al. 2010 raised it — backwards-decelerating ribs add another ~11–12 % of perceived speed-up. Miller 1968 Miller 1968 covers the 1 – 10 S band most single-file uploads sit inside.

Determinate Progress Bar + Percentage Count

Upload a 4.2 MB file. Naive: generic spinner with no progress signal. Tuned: optimistic filename render, determinate progress bar, success affordance with checkmark.

1 – 10 S
Interactive

Off

On

What is happening in the demo

The demo simulates a 4.2 MB file upload at p50 of 5 seconds (gamma-distributed). Click Upload on either side.

The naive side disables the button, shows a generic Loader2 spinner with "Uploading…" text, waits the full duration, then renders "uploaded." The user has no signal of how much of the upload is done at any given moment. They wait blind.

The tuned side does three things differently. First, the file's metadata (name, size in MB) appears immediately in optimistic form — the user sees what they are uploading without waiting for the server. Second, a determinate progress bar fills from 0 to 100 % in real time, polling every 50 ms — the user can see exactly how close to done they are. Third, on completion, the bar swaps to a checkmark + "Upload complete" affordance with primary-color emphasis.

A production version would also add the animated progress backwards-decelerating ribs for the additional ~12 % perceptual gain, and a cancellation control for the long tail.

What to tune

  1. Pre-action signal — start the upload on mousedown, not click. ~100 ms head-start (Fitch).
  2. First 1 s — pre-action button feedback within ~50 ms; no spinner yet.
  3. 1 – 10 s — determinate progress bar with backwards-decelerating ribs (Harrison 2010, +11–12 %).
  4. Past 10 s — engagement strip or hand-off to background sync.
  5. Completion — confirmation toast with the uploaded file's metadata; never silent.

When perceived performance hurts you here

The progress bar is honest only when it reflects reality. A bar that animates to 100 % over a fixed CSS duration regardless of actual upload progress will desync — finishing while the upload is still going, or sitting at 95 % while the bar drags. Either is worse than a blank wait. The XHR progress event, the Fetch streams API, or your upload library's progress callback is what the bar must track.

The other failure: shipping the bar without the success affordance. A bar that hits 100 % and stays at 100 % does not communicate "done" — the user is left wondering whether they can navigate away. Always pair the progress bar with an explicit success state.

Accessibility

  1. role="progressbar" plus aria-valuemin / valuemax / valuenow is mandatory. Screen readers cannot announce progress without it.
  2. aria-label describing what is uploading. "Uploading vacation-photo.jpg" beats "Uploading."
  3. Polite live region announcement at completion ("Upload complete") so screen-reader users register the success.
  4. Visible cancellation for the long tail. Pair with cancellation affordance — the principle is the same.
  5. prefers-reduced-motion — strip the rib animation; the width transition is a property change and stays.

Other patterns that fit

Same band, same surface — switch in whichever maps best to your UI.

Backwards-decelerating Progress Bar

Two bars, same actual duration. Naive: linear fill from 0 → 100 %. Tuned: same fill, but eased to be fast at the start and slow as it approaches the end, with backwards-moving ribbed pattern overlaid. Harrison et al. 2010 measured ~11–12 % perceived speed-up vs. linear at the same real wall-clock time. Free perception with no engineering cost.

1 – 10 S

Off

Press Run to start

On

Press Run to start

Animated Number Counter

Reframe a static result as a discovery. Naive: "847 results" snaps in fully formed when the data lands. Tuned: same number, but it counts up from 0 to 847 over ~700 ms with an ease-out curve. The user reads the count as a *finding* the system arrived at, not a static label.

100 MS – 1 S

Off

Press Run to start

On

Press Run to start

References · 3

  1. Myers 1985

    Myers, B. A. (1985). The importance of percent-done progress indicators for computer-human interfaces. Proceedings of CHI '85, 11–17. ~86 % preferred a determinate progress bar over a blank wait — file upload is the canonical use case.

  2. 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. ~11–12 % perceived speed-up from backwards-decelerating ribs on the progress bar.

  3. 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 1 – 10 S band most single-file uploads sit inside.