Basic

Scripts: defer, async, or move

A synchronous script in the head stops the parser at that point. The page cannot paint anything after it until the script downloads and runs. That single fact is most of the fix: do not block the parse.

What you will see

First paint moves earlier. If it does not, the script was not blocking and the change was cosmetic.

About 1 min of reading

Try It

Unblock the parse on one page

1

Find the blockers

grep -nE '

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

What it prints
The script downloads in parallel and runs after parse.
3

Check the dependency

grep -n 'document\.' public/js/main.js | head -3

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

What it prints
If it touches the DOM, defer is correct. If it must run before the parse reaches an inline handler, it needs restructuring.
4

Measure the change

reload with the tools open and compare the first-paint marker before and after

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

What it prints
First paint moves earlier. If it does not, the script was not blocking and the change was cosmetic.
Do not add defer to a script that writes to the document with document.write. Defer changes when it runs, and document.write depends on when.

Data Flow

Script tag to parse blocking
1 Parser reaches the script tag
↓
2 Synchronous: stop, download, run, continue
↓
3 defer: mark, finish parse, run in order
↓
4 async: mark, run when it arrives
Why this works
The order question first

Before choosing an attribute, ask whether the script depends on the DOM or on another script. If yes, defer. If it depends on nothing, async is fine.

Where the cost really is

A script that parses a large JSON on load costs CPU at the worst moment, right before the interaction. Move the work to when it is needed, not to page load.

Examples

defer by default

defer downloads in parallel and runs in order after parse. It is the safe default for anything that touches the DOM after the document is ready.

async only if order-free

async runs as soon as it arrives, so two async scripts have no guaranteed order. Use it only for a self-contained thing, like a single analytics beacon.

Move it out of the head

A script at the end of the body blocks nothing before it and needs no attribute. The attribute and the position solve the same problem; pick one and be consistent.

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.

← Fonts and the text that shifts
Previous Lesson
Fonts and the text that shifts
Next Lesson
Reading the numbers you collected
Reading the numbers you collected →