Skip to content
Merged

minor #1483

Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions 2-ui/5-loading/02-script-async-defer/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

In modern websites, scripts are often "heavier" than HTML: their download size is larger, and processing time is also longer.

When the browser loads HTML and comes across a `<script>...</script>` tag, it can't continue building DOM. It must execute the script right now. The same happens for external scripts `<script src="..."></script>`: the browser must wait until the script downloads, execute it, and only after process the rest of the page.
When the browser loads HTML and comes across a `<script>...</script>` tag, it can't continue building the DOM. It must execute the script right now. The same happens for external scripts `<script src="..."></script>`: the browser must wait until the script downloads, execute it, and only after process the rest of the page.

That leads to two important issues:

1. Scripts can't see DOM elements below them, so can't add handlers etc.
1. Scripts can't see DOM elements below them, so they can't add handlers etc.
2. If there's a bulky script at the top of the page, it "blocks the page". Users can't see the page content till it downloads and runs:

```html run height=100
Expand All @@ -31,7 +31,7 @@ There are some workarounds to that. For instance, we can put a script at the bot

But this solution is far from perfect. For example, the browser notices the script (and can start downloading it) only after it downloaded the full HTML document. For long HTML documents, that may be a noticeable delay.

Such things are invisible for people using very fast connections, but many people in the world still have slower internet speeds and use far-from-perfect mobile internet.
Such things are invisible for people using very fast connections, but many people in the world still have slow internet speeds and use a far-from-perfect mobile internet connecion.

Luckily, there are two `<script>` attributes that solve the problem for us: `defer` and `async`.

Expand Down Expand Up @@ -68,7 +68,7 @@ The following example demonstrates that:
```

1. The page content shows up immediately.
2. `DOMContentLoaded` waits for the deferred script. It only triggers when the script `(2)` is downloaded is executed.
2. `DOMContentLoaded` waits for the deferred script. It only triggers when the script `(2)` is downloaded and executed.

Deferred scripts keep their relative order, just like regular scripts.

Expand All @@ -94,8 +94,8 @@ The `defer` attribute is ignored if the `<script>` tag has no `src`.

The `async` attribute means that a script is completely independent:

- The page doesn't wait for async scripts, the contents is processed and displayed.
- `DOMContentLoaded` and async scripts don't wait each other:
- The page doesn't wait for async scripts, the contents are processed and displayed.
- `DOMContentLoaded` and async scripts don't wait for each other:
- `DOMContentLoaded` may happen both before an async script (if an async script finishes loading after the page is complete)
- ...or after an async script (if an async script is short or was in HTTP-cache)
- Other scripts don't wait for `async` scripts, and `async` scripts don't wait for them.
Expand Down Expand Up @@ -146,7 +146,6 @@ That is:
- They don't wait for anything, nothing waits for them.
- The script that loads first -- runs first ("load-first" order).

We can change the load-first order into the document order (just like regular scripts) by explicitly setting `async` property to `false`:

```js run
let script = document.createElement('script');
Expand Down Expand Up @@ -192,7 +191,7 @@ Please note that if you're using `defer`, then the page is visible *before* the

So the user may read the page, but some graphical components are probably not ready yet.

There should be "loading" indication in proper places, not-working buttons disabled, to clearly show the user what's ready and what's not.
There should be "loading" indications in proper places, set not-working buttons to disabled, to clearly show the user what's ready and what's not.
```

In practice, `defer` is used for scripts that need the whole DOM and/or their relative execution order is important. And `async` is used for independent scripts, like counters or ads. And their relative execution order does not matter.