Атрибуты async, defer в JS
Загрузка страницы в браузер
Когда HTML страница попадает в браузер, то сразу запускается процесс распознавания: сканируется код страницы сверху вниз, формируется DOM-дерево, загружаются CSS стили, шрифты. Тег за тегом на странице строится верстка. Когда в конце страницы браузер видит тег скрипта, то загружает код скрипта и начинает взаимодействовать с ним.
Ошибка новичков
В чем состоит типичная ошибка новичков? Они тег script помещают не в конец страницы, а между тегами head. Чего категорически нельзя делать. Что будет если DOM-дерево еще не успело построиться, а скрипт уже начал взаимодействовать с элементами, которых еще нет на странице? Это неизбежно приведет к ошибке и скрипт может заблокировать страницу из-за порочной цепочки: Скрипт ждет загрузки нужных ему элементов, а загрузка элементов встала на паузу из-за зависания скрипта. В итоге сайт зависает и становится не работоспособным.
<script src="script.js"></script>
Загрузка скрипта на страницу
Но не все так просто, даже при правильном размещении тега script, все равно может возникнуть проблема. Причина - объемная HTML структура на больших проектах. Пока загрузятся все теги и дойдет очередь до скрипта, пройдёт сколько-то времени. Тогда у пользователей с медленным интернетом, задержки будут значительными. Поэтому были придуманы два атрибута defer и async, которые помогут решить эту проблему.
Атрибут defer
Атрибут defer сообщает браузеру, что он должен продолжать обрабатывать страницу и запускать скрипт, только после готовности DOM-дерева. Скрипты с атрибутом defer никогда не заблокирует страницу. Пример ниже демонстрирует, что допустимо ставить тег скрипт выше элементов страницы, если указан атрибут defer.
<body>
<head>
<script defer src="script.js"></script>
</head>
<h3>Атрибут defer</h3>
<p>загружает по порядку расположения.</p>
</body>
Отложенные скрипты с помощью атрибута defer, сохраняют порядок относительно друг друга, как и скрипты без данного атрибута. В теории все ссылки на скрипты с тегом defer можно поместить в тег head, но в реальной жизни так все равно не нужно делать. Например сервис Google PageSpeed на такое будет ругаться и занижать оценку по скорости загрузки сайта.
Атрибут async
Асинхронные скрипты с атрибутом async, не ждут загрузки элементов страницы и не ждут загрузки друг друга. Они абсолютно независимые. Мы не знаем какой из двух скриптов загрузится первым и начнет работать. Чем полезно такое на первый взгляд непредсказуемое поведение скрипта? Дело в том, что иногда мы будем подключать различные сторонние скрипты, которые не особо привязаны к DOM-структуре. Например сторонним скриптам, таким как метрикам и счетчикам главное отловить, что пользователь зашел на сайт.
<body>
<head>
<script async src="script.js"></script>
<script async src="common.js"></script>
</head>
<h3>Атрибут async</h3>
<p>не зависит от DOM-структуры.</p>
</body>
Когда мы используем скрипты с атрибутом async, то мы должны быть абсолютно точно уверены, что этот скрипт не зависит от DOM-структуры. Для него совершенно не важно успела она сформироваться или нет. Кроме того он должен не зависеть от каких-то других скриптов и библиотек.
Итоги
Атрибуты defer и async добавляют гибкости при подключении внешних скриптов к HTML документу. Если мы применяем атрибут async к тегу script, то это означает следующее: Когда браузер дойдет до скрипта, то он не будет ждать пока скрипт загрузится целиком, а продолжит его загрузку в фоновом режиме и продолжит считывание файла дальше. Это может быть актуально например, если тег script подключен между тегами head. Обычно таким образом подключают к сайту счетчики и веб-аналитику.
<!-- Пример подключения Google Analytics -->
<script async src="https://google-analytics.com/analytics.js"></script>
Атрибут defer делает тоже самое, но с одним небольшим исключением. Если на странице есть еще один тег script с атрибутом defer, то браузер обещает нам, что даже несмотря на асинхронную загрузку данного скрипта в фоновом режиме, порядок загрузки скриптов и их выполнение сохранится. Первым загрузится скрипт, который выше расположен на странице, независимо от размера этого скрипта.
-
- Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.