Advanced

Deferring work that is not needed yet

Loading is not the only cost. Work that runs before it is needed costs the same budget and buys nothing. The discipline is to ask when the result is needed, and to run the work at that moment rather than at load.

What you will see

Both drop if the work was on the path. If only the count drops, the work was never on the path.

About 1 min of reading

Try It

Move one cost off the load

1

Find load-time parsing

grep -nE 'JSON\.parse|readFileSync|loadAll' public/js/*.js utils/*.js | head -10

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Work that runs at module load rather than at use.
2

Wrap it in a cache

printf 'let cache = null;\nfunction get() { if (cache === null) cache = expensive(); return cache; }\n' | tee -a tmp/pattern.js

Before you run it, say out loud what it will print. Then open the answer.

What it prints
A function that does the work on first call and returns the stored value after.
3

Lazy the images

grep -oE '

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The second count should cover every image below the first screen.
4

Measure the win

reload and compare the time to first paint and the request count

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Both drop if the work was on the path. If only the count drops, the work was never on the path.
Do not lazy-load a resource a layout calculation depends on. Reserve its box first, or the measurement changes when it arrives.

Data Flow

Load-time work to use-time work
1 Feature is requested by the user
↓
2 Cache is checked
↓
3 Work runs once on first use
↓
4 Result is cached for later calls
Why this works
The question to ask per feature

Does the first paint need this? If no, defer it. If the user needs it in half of sessions, deferring only moves the cost to a worse place.

Where lazy breaks correctness

A lazy image that is needed for a layout calculation arrives late and changes the measurement. Reserve the box so the measurement does not depend on arrival.

Examples

Lazy images below the fold

loading="lazy" on an image the first paint does not show. The browser skips the request until the box is near the viewport, which removes it from the path.

Parse data on use, not on load

A large JSON parsed at page load costs CPU before the user chose anything. Parse when the feature is opened, and cache the result for the next call.

Cost of a lazy thing

Lazy loading moves the cost later, it does not remove it. If the user always needs it, lazy is a wash and the real fix is a smaller payload.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← The critical path and what to inline
Previous Lesson
The critical path and what to inline
Next Lesson
Compression, minification, and what not to compress
Compression, minification, and what not to compress →