Perceived Performance

The only kind that really matters.

Hi, I'm Eli.

I make weird stuff on the internet

Today I'll be shrieking about

  • Why focusing on perceived performance is smart
  • How humans perceive time
  • A box of tricks to manage perceived loading time
  • Predictive preloading

Why Perceived
Performance Matters

Web Performance
is a matter of time.

Time is a funny thing.

Objective time
vs.
Subjective time

We've gotten INSANELY good at objective performance.

Code minification

Image optimization

Critical Rendering Path

Tree shaking

Code splitting

Lazyloading

Edge node caching

SVG spritesheets

We optimize for objective time.

Even with perceived perf!

What if users don't notice?

Just Noticeable Difference.

Time differences of 20% or less are imperceptible.

Steve Seow, Microsoft

Shoot for 30% speedup.

We don't live inside of a web performance blog post.

Focus on the subjective.
Better 💥 for 🤑.

How Humans
Sense Time

Active phase
vs.
Passive phase

Humans tend to overestimate passive time by 36%.

Richard Larson, MIT

🚗💨
vs.
🚐🚗🚐

Takes about ~1 second to transition to a passive state

Nielsen Norman Group

How do we use this

  • Keep users in an active state, keep them from entering a passive state.
  • Make passive phases feel faster than they actually are.

Keep users active

Key for short durations.

What we can do

  • Don't tell users they're waiting.
  • Respond to users immediately, even if nothing is happening.
  • Keep users in flow with more responsive event listeners.

#Resist loading
indicators

Woah. Woah. Woah.

Slow down here.

Don't use loaders?

But perceived perf?

Loaders tell users
that they have to wait.

Adding a loader prematurely
puts them in a passive state.

As waits approach ~1 second,
start to use loaders.

Immediate
Feedback

Immediacy keeps users from entering a passive state.

Stay :active, kids!

Optimism!
Optimism!
Optimism!

Better Event
Listeners

Takes ~1 second to
enter a passive state.

React as soon as
the user signals intent.

Click: button up
vs.
Mousedown: button down

Mousedown gives you a
100-150ms head start.

:active animations
buy you more time

~200ms duration gives you a +50ms bonus

Works on touch devices too!

Begin on touchstart.

Cancel on touchmove.

Un-suck passive waits

You start to lose people
at ~1-4s of waiting.

Critical to get this right.

What we can do

  • The right loading animation can make time pass more quickly.
  • Adapt loading scheme to each user.
  • Distract with shiny objects.

The Perfect
Progress Bar

Uncertain waits feel longer.

David Maister

Progress bars give
users certainty.

Animation makes a difference.

Bars with accelerating
bands feel 12% faster.

Chris Harrison, Zhiquan Yeo, and Scott Hudson, Carnegie Mellon

But what about spinners?

Meh.

Spinners aren't versatile

  • < ~1s? Don't indicate loading.
  • > ~2s? Really need a progress bar.
  • Only useful between 1 and 2 seconds.

Real progress bars
can be overkill.

Most progress bars are fake.

Many are pretty 💩y.

Adaptive loading

Keep it real…ish.

Measure requests.

						
const API_EXPECTED_TIME = 1000;
const SOME_OTHER_EXPECTED_TIME = 2000;

function init() {
	let t0 = performance.now();
	fetch(`${VERY_SERIOUS_API_URL}`).then(response => {
		const apiRoundtrip = performance.now() - t0;
		setPerformanceScalar(apiRoundtrip, API_EXPECTED_TIME);
		// Do stuff
	});
}

function setPerformanceScalar(observed, expected) {
	const performanceScalar = observed / expected;
	// ...
	// tuck this away in app state, local storage, a global variable, etc
}

function getPerformanceScalar() {
	// retreive your saved performance data
	return performanceScalar;
}

//...

Some tips

  • Normalize for resource or payload.
  • Adapt your whole loading scheme.
  • Set baseline times with your test runner.

Occupy Users'
Attention

Reticulating splines.

We can learn from gamedevs.

If this feels like cheating,
that's because it is.

You dirty cheaters, you.

Predictive
Preloading

React as soon as
users signal intent.

What if we could
predict their intent?

Gamedevs do this all the time.

You may have done it
without realizing.

Checkout form

~2 second head start!

CTA Button

Exploiting behavioral quirks

  • People tend to watch hover & active animations.
  • People necessarily slow their cursor as it approaches a target.

People watch hovers.

Fancy hovers buy you
up to 600ms extra.

Detect decelleration
with Futurelink!

https://github.com/SamKnows/futurelink

Elaborate Hover + Futurelink
At least ~1.5 second head start!

Predictive preloading is a very powerful tool.

Use it wisely.

Mitigate risk with data.

Dry run first.

TLDR;

Perceived perf is
low hanging fruit.

Provide users immediate, accurate, live feedback.

Tailor your solution
to individual users.

React quickly to
and extrapolate intent.

Introduce predictive preloading
bit by bit.

At the end of the day, what matters is how it feels.

Focus on the user.

Thanks y'all!

http://assets.eli.wtf/talks/perceived-perf-fluent-2017

http://eli.wtf/fun