Html head script async

Скрипты: async, defer

В современных сайтах скрипты обычно «тяжелее», чем HTML: они весят больше, дольше обрабатываются.

Когда браузер загружает HTML и доходит до тега , он не может продолжать строить DOM. Он должен сначала выполнить скрипт. То же самое происходит и с внешними скриптами : браузер должен подождать, пока загрузится скрипт, выполнить его, и только затем обработать остальную страницу.

Это ведёт к двум важным проблемам:

  1. Скрипты не видят DOM-элементы ниже себя, поэтому к ним нельзя добавить обработчики и т.д.
  2. Если вверху страницы объёмный скрипт, он «блокирует» страницу. Пользователи не видят содержимое страницы, пока он не загрузится и не запустится:

. содержимое перед скриптом.

. содержимое после скрипта.

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

 . всё содержимое над скриптом.  

Но это решение далеко от идеального. Например, браузер замечает скрипт (и может начать загружать его) только после того, как он полностью загрузил HTML-документ. В случае с длинными HTML-страницами это может создать заметную задержку.

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

К счастью, есть два атрибута тега , которые решают нашу проблему: defer и async .

defer

Атрибут defer сообщает браузеру, что он должен продолжать обрабатывать страницу и загружать скрипт в фоновом режиме, а затем запустить этот скрипт, когда DOM дерево будет полностью построено.

Вот тот же пример, что и выше, но с defer :

. содержимое перед скриптом.

. содержимое после скрипта.

  • Скрипты с defer никогда не блокируют страницу.
  • Скрипты с defer всегда выполняются, когда дерево DOM готово, но до события DOMContentLoaded .

Следующий пример это показывает:

. содержимое до скрипта.

// (2)

. содержимое после скрипта.

  1. Содержимое страницы отобразится мгновенно.
  2. Событие DOMContentLoaded подождёт отложенный скрипт. Оно будет сгенерировано, только когда скрипт (2) будет загружен и выполнен.

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

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

Браузеры сканируют страницу на предмет скриптов и загружают их параллельно в целях увеличения производительности. Поэтому и в примере выше оба скрипта скачиваются параллельно. small.js скорее всего загрузится первым.

Но спецификация требует последовательного выполнения скриптов согласно порядку в документе, поэтому он подождёт выполнения long.js .

Атрибут defer будет проигнорирован, если в теге нет src .

async

Атрибут async означает, что скрипт абсолютно независим:

  • Страница не ждёт асинхронных скриптов, содержимое обрабатывается и отображается.
  • Событие DOMContentLoaded и асинхронные скрипты не ждут друг друга:
    • DOMContentLoaded может произойти как до асинхронного скрипта (если асинхронный скрипт завершит загрузку после того, как страница будет готова),
    • …так и после асинхронного скрипта (если он короткий или уже содержится в HTTP-кеше)

    Так что если у нас есть несколько скриптов с async , они могут выполняться в любом порядке. То, что первое загрузится – запустится в первую очередь:

    . содержимое перед скриптами.

    . содержимое после скриптов.

    1. Содержимое страницы отображается сразу же : async его не блокирует.
    2. DOMContentLoaded может произойти как до, так и после async , никаких гарантий нет.
    3. Асинхронные скрипты не ждут друг друга. Меньший скрипт small.js идёт вторым, но скорее всего загрузится раньше long.js , поэтому и запустится первым. То есть, скрипты выполняются в порядке загрузки.

    Асинхронные скрипты очень полезны для добавления на страницу сторонних скриптов: счётчиков, рекламы и т.д. Они не зависят от наших скриптов, и мы тоже не должны ждать их:

    Динамически загружаемые скрипты

    Мы можем также добавить скрипт и динамически, с помощью JavaScript:

    let script = document.createElement('script'); script.src = "/article/script-async-defer/long.js"; document.body.append(script); // (*)

    Скрипт начнёт загружаться, как только он будет добавлен в документ (*) .

    Динамически загружаемые скрипты по умолчанию ведут себя как «async».

    • Они никого не ждут, и их никто не ждёт.
    • Скрипт, который загружается первым – запускается первым (в порядке загрузки).

    Мы можем изменить относительный порядок скриптов с «первый загрузился – первый выполнился» на порядок, в котором они идут в документе (как в обычных скриптах) с помощью явной установки свойства async в false :

    let script = document.createElement('script'); script.src = "/article/script-async-defer/long.js"; script.async = false; document.body.append(script);

    Например, здесь мы добавляем два скрипта. Без script.async=false они запускались бы в порядке загрузки ( small.js скорее всего запустился бы раньше). Но с этим флагом порядок будет как в документе:

    function loadScript(src) < let script = document.createElement('script'); script.src = src; script.async = false; document.body.append(script); >// long.js запускается первым, так как async=false loadScript("/article/script-async-defer/long.js"); loadScript("/article/script-async-defer/small.js");

    Итого

    У async и defer есть кое-что общее: они не блокируют отрисовку страницы. Так что пользователь может просмотреть содержимое страницы и ознакомиться с ней сразу же.

    Но есть и значимые различия:

    Порядок DOMContentLoaded
    async Порядок загрузки (кто загрузится первым, тот и сработает). Не имеет значения. Может загрузиться и выполниться до того, как страница полностью загрузится. Такое случается, если скрипты маленькие или хранятся в кеше, а документ достаточно большой.
    defer Порядок документа (как расположены в документе). Выполняется после того, как документ загружен и обработан (ждёт), непосредственно перед DOMContentLoaded .

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

    Пользователь может знакомиться с содержимым страницы, читать её, но графические компоненты пока отключены.

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

    На практике defer используется для скриптов, которым требуется доступ ко всему DOM и/или важен их относительный порядок выполнения.

    А async хорош для независимых скриптов, например счётчиков и рекламы, относительный порядок выполнения которых не играет роли.

    Источник

    Атрибут async

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

    Синтаксис

    Значения

    Значение по умолчанию

    По умолчанию этот атрибут выключен.

    В данном примере загружается содержимое страницы и одновременно выполняется скрипт, который выводит сообщение через функцию alert() . Без атрибута async содержимое страницы не отображается, пока мы не закроем окно с сообщением.

    Не выкладывайте свой код напрямую в комментариях, он отображается некорректно. Воспользуйтесь сервисом cssdeck.com или jsfiddle.net, сохраните код и в комментариях дайте на него ссылку. Так и результат сразу увидят.

    Типы тегов

    HTML5

    Блочные элементы

    Строчные элементы

    Универсальные элементы

    Нестандартные теги

    Осуждаемые теги

    Видео

    Документ

    Звук

    Изображения

    Объекты

    Скрипты

    Списки

    Ссылки

    Таблицы

    Текст

    Форматирование

    Формы

    Фреймы

    Источник

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

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

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

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

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

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

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

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

    html> head> title>Titletitle> script src="script.js">script> head> body> . body> html> 

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

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

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

    async и defer

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

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

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

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

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

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

    Если async и defer отсутствуют в

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

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

    Если async и defer отсутствуют в

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

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

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

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

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

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

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

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

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

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

    domInteractive

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

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

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

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

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

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

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

    Источник

    Читайте также:  Java arraylist get by object
Оцените статью