Главная | Все статьи | Код

Руководство: как увеличить скорость загрузки страницы со скриптами с помощью defer и async

Время чтения статьи ~4 минуты
Руководство: как увеличить скорость загрузки страницы со скриптами с помощью ... главное изображение

JS-скрипты, неудачно расположенные в HTML-коде, могут значительно снизить скорость загрузки страницы. Разберемся, как повысить скорость загрузки в старых версиях браузеров и как правильно использовать async и defer, которые поддерживаются в новых версиях.

Это адаптированный перевод статьи Efficiently load JavaScript with defer and async из блога проекта flaviocopes. Повествование ведется от лица автора оригинала.

Расположение имеет значение

Стандартный способ встраивания скрипта в HTML-код страницы выглядит так:

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

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

Классический подход к обучению HTML предполагает, что теги скрипта должны находиться в <head>:

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

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

Распространенное решение проблемы — перенос скрипта в нижнюю часть страницы, перед закрывающим тегом </body>. В этом случае скрипт выполняется после того, как вся страница уже проанализирована до тега.

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

async и defer

Прежде чем начать, стоит уточнить, что использование обоих атрибутов накладывает некоторые ограничения, а приведенное ниже руководство по времени загрузки — не исчерпывающее.

Синтаксически и async и defer — булевые атрибуты, которые используются следующим образом:

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

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

Проверить совместимость атрибутов с разными версиями браузеров можно по этим таблицам: раз и два

Важно отметить, что оба атрибута стоит использовать только в верхней части страницы (в <head>): перенос в <body> делает их совершенно бесполезными.

Производительность

Если async и defer отсутствуют в <head>

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

Читайте также: Как сохранять фокус на протяжении всего обучения: советы от Хекслета

Если async и defer отсутствуют в <body>

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

Если async находится в <head>

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

Если defer находится в <head>

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

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

Блокировка синтаксического анализа

async приостанавливает синтаксический анализ страницы, а defer — нет.

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

Ни async, ни defer не блокируют рендеринг — этот процесс полностью зависит от кода на странице. Поэтому важно убедиться, что сценарии запускаются после события onLoad.

domInteractive

Скрипты defer выполняются сразу после события domInteractive. Последнее, в свою очередь, происходит после загрузки, анализа и построения DOM HTML.

СSS и изображения на этом этапе еще не проанализированы и не загружены: как только это произойдет, браузер сначала выдаст событие domComplete, а затем — onLoad.

Порядок выполнения

Еще один аргумент за использование defer — скрипты, помеченные как async, выполняются в случайном порядке, тогда как скрипты с defer — в строго определенном.

Как ускорить загрузку страницы

Лучший способ — прописать скрипты в <head> и добавить атрибут defer в тег script. Этот сценарий быстро запускает событие domInteractive :

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

Никогда не останавливайтесь: В программировании говорят, что нужно постоянно учиться даже для того, чтобы просто находиться на месте. Развивайтесь с нами — на Хекслете есть сотни курсов по разработке на разных языках и технологиях

Аватар пользователя Oleg Sabitov
Oleg Sabitov 15 февраля 2022
48
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка фронтенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 18 апреля
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Django
10 месяцев
с нуля
Старт 18 апреля
профессия
от 6 183 ₽ в месяц
Ручное тестирование веб-приложений
4 месяца
с нуля
Старт 18 апреля
профессия
от 6 300 ₽ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 18 апреля
профессия
от 5 025 ₽ в месяц
новый
Сбор, анализ и интерпретация данных
9 месяцев
с нуля
Старт 18 апреля
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Laravel
10 месяцев
с нуля
Старт 18 апреля
профессия
от 5 840 ₽ в месяц
Создание веб-приложений со скоростью света
5 месяцев
c опытом
Старт 18 апреля
профессия
от 9 900 ₽ в месяц
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
16 месяцев
с нуля
Старт 18 апреля
профессия
от 6 300 ₽ в месяц
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 18 апреля
профессия
новый
Автоматизированное тестирование веб-приложений на JavaScript
8 месяцев
c опытом
в разработке
Старт 18 апреля
профессия
Верстка с использованием последних стандартов CSS
5 месяцев
с нуля
Старт в любое время