Эффективно загружайте JavaScript с помощью defer и async

При загрузке скрипта на HTML-страницу нужно быть осторожным, чтобы не повредить загрузке страницы. Время загрузки зависит от того, где и как вы добавляете свои скрипты на HTML-страницу.

При загрузке скрипта на HTML-страницу нужно быть осторожным, чтобы не повредить загрузке страницы.

Скрипт традиционно включается на страницу таким образом:

<script src="script.js"></script>

всякий раз, когда синтаксический анализатор HTML находит эту строку, будет сделан запрос на выборку сценария, и сценарий будет выполнен.

Как только этот процесс будет завершен, синтаксический анализ может возобновиться, а остальная часть HTML может быть проанализирована.

Как вы понимаете, эта операция может сильно повлиять на время загрузки страницы.

Если скрипт загружается немного дольше, чем ожидалось, например, если сеть немного медленная или вы используете мобильное устройство, а соединение немного ненадежное, посетитель, скорее всего, увидит пустую страницу, пока скрипт не будет загружен и выполнен.

Позиция имеет значение

Когда вы впервые изучаете HTML, вам говорят, что теги сценария живут в<head>тег:

<html>
  <head>
    <title>Title</title>
    <script src="script.js"></script>
  </head>
  <body>
    ...
  </body>
</html>

Как я уже говорил вам ранее, когда синтаксический анализатор находит эту строку, он получает сценарий и выполняет его.потом, после выполнения этой задачи он переходит к синтаксическому анализу тела.

Это плохо, потому что здесь много задержек. Очень распространенное решение этой проблемы - поставитьscriptтег внизу страницы, непосредственно перед закрытием</body>тег.

При этом сценарий загружается и выполняется после того, как вся страница уже проанализирована и загружена, что являетсяогромное улучшениенадheadальтернатива.

Это лучшее, что вы можете сделать, если вам нужно поддерживать старые браузеры, которые не поддерживают две относительно недавние функции HTML:asyncиdefer.

Асинхронный и отложенный

Оба async и defer являются логическими атрибутами. Их использование похоже:

<script async src="script.js"></script>
<script defer src="script.js"></script>

если вы укажете оба,asyncимеет приоритет в современных браузерах, в то время как старые браузеры, поддерживающиеdeferно нетasyncвернется кdefer.

Для таблицы поддержки проверьте caniuse.com для asynchttps://caniuse.com/#feat=script-asyncи на отсрочкуhttps://caniuse.com/#feat=script-defer

Эти атрибуты имеют смысл только при использовании скрипта вheadчасти страницы, и они бесполезны, если вы поместите сценарий вbodyнижний колонтитул, как мы видели выше.

Сравнение производительности

Нет отсрочки или асинхронности, в голове

Вот как страница загружает скрипт без задержки или асинхронности, вставивheadчасть страницы:

Without defer or async, in the head

Синтаксический анализ приостанавливается до тех пор, пока сценарий не будет извлечен и выполнен. Как только это будет сделано, синтаксический анализ возобновится.

Нет отсрочки или асинхронности в теле

Вот как страница загружает скрипт без задержек или асинхронности, помещенных в конецbodyтег, непосредственно перед закрытием:

Without defer or async, in the body end

Синтаксический анализ выполняется без пауз, и когда он завершается, выполняется выборка и выполнение сценария. Анализ выполняется до того, как скрипт будет загружен, поэтому страница отображается для пользователя раньше, чем в предыдущем примере.

С async в голове

Вот как страница загружает скрипт сasync, вставьтеheadтег:

With async

Сценарий извлекается асинхронно, и когда он готов, синтаксический анализ HTML приостанавливается для выполнения сценария, а затем возобновляется.

С отсрочкой в голове

Вот как страница загружает скрипт сdefer, вставьтеheadтег:

With defer

Сценарий извлекается асинхронно и выполняется только после завершения анализа HTML.

Парсинг заканчивается так же, как когда мы помещаем скрипт в конецbodyтег, но в целом выполнение сценария заканчивается задолго до этого, потому что сценарий был загружен параллельно с синтаксическим анализом HTML.

Так что это выигрышное решение с точки зрения скорости 🏆

Блокировка парсинга

asyncблокирует парсинг страницы, покаdeferне.

Блокировка рендеринга

Ни одинasyncниdeferгарантировать что-либо при блокировке рендеринга. Это зависит от вас и вашего сценария (например, убедитесь, что ваши сценарии запускаются послеonLoad) мероприятие.

domInteractive

Сценарии отмеченыdeferвыполняются сразу послеdomInteractiveсобытие, которое происходит после загрузки, анализа HTML иДОМпостроено.

CSS и изображения на этом этапе еще предстоит проанализировать и загрузить.

Как только это будет сделано, браузер выдаст сообщениеdomCompleteсобытие, а затемonLoad.

domInteractiveважен, потому что его время считается мерой воспринимаемой скорости загрузки.Посмотреть MDNдля большего.

Ведение порядка

Другой случай проdefer: скрипты отмеченыasyncвыполняются в случайном порядке, когда они становятся доступными. Сценарии отмеченыdeferвыполняются (после завершения анализа) в том порядке, в котором они определены в разметке.

Просто скажи мне лучший способ

Лучшее, что можно сделать, чтобы ускорить загрузку вашей страницы при использовании скриптов, - это поместить их вheadи добавьтеdeferатрибут вашегоscriptтег:

<script defer src="script.js"></script>

Это сценарий, который запускает более быстрыйdomInteractiveмероприятие.

Учитывая плюсыdefer, кажется, лучший выбор, чемasyncв самых разных сценариях.

Если вас не устраивает отсрочка первого рендеринга страницы, убедитесь, что при анализе страницы нужный JavaScript уже выполняется.

Скачать мою бесплатнуюРуководство для начинающих по JavaScript


Больше руководств по браузеру: