😎Тема корисна, а ще її буває питають на співбесідах, то ж давайте розбиратися.
✍️ Коли браузер завантажує нашу сторінку - спершу він бачить її просто як звичайний текст. Оскільки працювати з текстом не зручно, відбувається токенізація - розбиття тексту на токени, які паралельно перетворюються на Document Object Module або DOM який вже буде відмальовуватися на сторінці. Цікавим моментом є те, що браузеру не потрібно чекати завантаження всієї сторінки - він буде відмальовувати контент паралельно із завантаженням. Це значно прискорює момент коли наш користувач зможе побачити контент і це дійсно круто.
Але що відбудиться, коли браузер зустріне тег
script? Насправді, це залежить від того, який саме скрипт він побачить.
Якщо браузер зустріне звичайний скрипт (який ще називається синхронним):
<script src="/index.js"></script>
Він зупинить парсинг HTML і почне завантажувати цей скрипт. Коли завантаження закінчиться, він виконає цей скрипт. І лише після його виконання браузер продовжить парсинг та відображення сторінки. Така поведінка призводить до того, що, поки ваш скрипт вантажиться та виконується, новий контент на сторінці не з'являється (хоча дещо на фоні все ж таки буде відбуватися, але це вже оптимізації самих браузерів). Така поведінка не дуже сприяє гарному користувацькому досвіду.
Тому з'явилися спеціальні атрибути, які змінюють цю поведінку.
1️⃣ Перший атрибут це
async: <script async src="/index.js"></script>
Він каже браузеру буквально наступне:
- Коли ти побачиш цей скрипт, не потрібно зупинятися. Просто почни його завантажувати у фоновому режимі, а коли завантажиш, от тоді вже виконуй.
Це дає змогу продовжувати показувати контент, паралельно із завантаженням скрипту, що вже виглядає краще.
Але! Коли скрипт завантажиться, він почне виконуватися, а це зупинить парсинг та відображення сторінки, якщо вона не встигла повністю завантажитися. Ще один мінус в тому, що є ймовірність, що деякі елементи сторінки не встигнуть завантажитися і скрипт не зможе з ними працювати. Плюс до цього - порядок виконання асинхронних скриптів не гарантований, вони виконуються по мірі завантаження.
2️⃣ Другий атрибут це
defer<script defer src="/index.js"></script>
Його завантаження теж відбувається у фоновому режимі і не блокує відображення контенту. Але виконання скрипту буде відкладено до повного завантаження сторінки. Таким чином відображення змісту сторінки не буде заблоковане виконанням скрипту, а контент, в свою чергу, завжди буде готовий до взаємодії з кодом. Якщо у вас декілька defer скриптів, вони будуть виконані в тому самому порядку як на сторінці.
З цікавого, якщо застосувати
async та defer разом, буде вибрана стратегія deferБільш детальніше англійською тут
Ілюстрацію цього всього веселого - дивись постом вище
@reactbeginners