Script defer что это
Перейти к содержимому

Script defer что это

  • автор:

Скрипты: 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 скрипты сохраняют порядок относительно друг друга, как и обычные скрипты.

Допустим, у нас есть два скрипта c defer : small.js и long.js :

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

…Но defer не только говорит браузеру «не блокировать рендеринг», он также обеспечивает правильную последовательность выполнения скриптов. Даже если small.js загрузится первым, он будет ждать выполнения long.js .

Это важно в тех случаях, когда нам сначала нужно загрузить JavaScript-библиотеку, а затем скрипт, который от неё зависит.

Атрибут defer предназначен только для внешних скриптов

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

async

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

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

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

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

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

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

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

    Атрибут async предназначен только для внешних скриптов

    Как и в случае с defer , атрибут async будет проигнорирован, если в теге нет src .

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

    Мы можем также добавить скрипт и динамически, с помощью 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 хорош для независимых скриптов, например счётчиков и рекламы, относительный порядок выполнения которых не играет роли.

    : элемент для написания скриптов

    HTML Элемент используется для встраивания или подключения исполняемого JavaScript кода. Элемент также может использоваться с другими языками, такими как GLSL (en-US) от WebGL.

    Content categories Метаданные, Потоковый контент, Фразовый контент.
    Допустимый контент Динамический скрипт, используя атрибут text/javascript .
    Пропуск тегов Нет. Открывающий и закрывающий теги обязательны
    Допустимые родители Любые элементы в которых разрешены метаданные или фразовый контент
    Допустимые ARIA-роли нет
    DOM-интерфейс HTMLScriptElement

    Атрибуты

    Это логический атрибут, указывающий браузеру, если возможно, загружать скрипт, указанный в атрибуте src , асинхронно.

    Предупреждение: Атрибут async не будет оказывать никакого эффекта, если атрибут src отсутствует. Обычно браузеры загружают синхронно, (т.е. async=»false» ) во время разбора документа. Динамически вставленный (используя, например, document.createElement ) по умолчанию загружаются браузером асинхронно, поэтому для включения синхронной загрузки (т.е. когда скрипты загружаются в порядке их вставки) укажите async=»false» .

    Обычные элементы тега script передают мало информации в window.onerror для скриптов, которые не проходят проверку CORS (en-US) . Чтобы разрешить ведение журнала ошибок сайта, которые используют отдельный домен для статических файлов (например, изображение, видео-файл, CSS-стили или Javascript-код), используйте атрибут crossorigin . Посмотрите статью «настройки атрибутов CORS» для более наглядного объяснения его допустимых аргументов.

    Это логический атрибут, указывающий браузеру, что скрипт должен выполняться после разбора документа, но до события DOMContentLoaded (en-US) . Скрипты с атрибутом defer будут предотвращать запуск события DOMContentLoaded (en-US) до тех пор, пока скрипт не загрузится полностью и не завершится его инициализация.

    Предупреждение: Атрибут defer не будет оказывать никакого эффекта, если атрибут src отсутствует. Чтобы достигнуть такого же эффекта для динамически вставленных скриптов используйте async=false . Скрипты с атрибутом defer будут выполняться в том порядке, в котором они появились при разборе документа.

    Этот атрибут содержит встроенные метаданные, которые агент пользователя (браузер) может использовать для проверки того, что выбранный ресурс был доставлен без непредвиденных манипуляций. Смотрите Целостность субресурса (en-US) .

    Булевый атрибут, который устанавливается для того, чтобы скрипт не выполнялся в браузерах, поддерживающих ES6-модули (англ.). Таким образом, может быть использован для предоставления резервных сценариев в старых браузерах, которые не поддерживают модульный код JavaScript.

    Криптографический одноразовый номер (номер, используемый один раз) для внесения встроенных скриптов в белый список в script-src Content-Security-Policy (en-US) . Сервер должен генерировать уникальное одноразовое значение каждый раз, когда он передает политику. Крайне важно предоставить одноразовый номер, который нельзя угадать, поскольку в противном случае обход политики ресурса является тривиальным.

    Определяет URI внешнего скрипта; является альтернативой встраиванию скрипта непосредственно в документ.

    Предупреждение: Если у элемента script будет указан атрибут src , то он не должен иметь встроенный скрипт между тегами.

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

    Этот атрибут указывает тип представленного скрипта. Значение этого атрибута будет находиться в одной из следующих категорий:

    • Атрибут не установлен (по-умолчанию), пустая строка или установлен как MIME-тип JavaScript
      • : Обозначает, что скрипт является «классическим скриптом», содержащим JavaScript-код. Рекомендуется не указывать MIME-тип, а пропускать атрибут вообще. MIME-типы JavaScript указаны в спецификации.
      • : Данное значение даёт браузеру инструкцию, что код является JavaScript-модулем. Обработка содержимого скрипта отложенная. Атрибуты charset и defer игнорируются. Для дополнительной информации по использованию module , смотрите руководство по JavaScript-модулям. В отличие от классчических скриптов, модули требуют использования CORS-протокола для cross-origin загрузок.
      • : Данное значение сигнализирует о том, что содержимое тега является словарём импортов. Словарь импортов — это JSON-объект, который может использоваться для задания алиасов при импорте JavaScript-модулей.

      Устаревшие атрибуты

      Если присутствует, его значение должно соответствовать «utf-8» без учета регистра ASCII. И в том, и в другом случае нет необходимости указывать атрибут charset, поскольку документы должны использовать UTF-8, а элемент script наследует свою кодировку символов от документа.

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

      Примечания

      Элемент без указания атрибутов async , defer или type=»module» , а также встроенный скрипт, загружается и выполняется сразу, до того как браузер продолжит разбор документа.

      Для обработки скрипт должен иметь тип данных text/javascript , но браузеры снисходительны и блокируют обработку только в том случае, если скрипт представляет данные одного из типов: изображение ( image/* ); видео ( video/* ); аудио ( audio/* ); или text/csv . Если скрипт заблокирован, элементу отправляется событие error (en-US) , если не было отправлено событие load (en-US) .

      Примеры

      Основное использование

      Эти примеры показывают как импортировать скрипт используя элемент в HTML4 и HTML5.

      script type="text/javascript" src="javascript.js"> script> script src="javascript.js"> script> 

      Фолбэк-модуль

      Браузеры, поддерживающие использование значения module для атрибута type , игнорируют любые скрипты с атрибутом nomodule . Это разрешает использовать модульные скрипты, и в тот же самый момент позволяет использовать nomodule- скрипты для браузеров без поддержки модульных скриптов.

      script type="module" src="main.mjs"> script> script nomodule src="fallback.js"> script> 

      Спецификации

      Specification
      HTML Standard
      # the-script-element

      Совместимость с браузерами

      BCD tables only load in the browser

      Смотрите также

      • document.currentScript
      • Статья Flavio Copes о эффективной загрузке JavaScript и различиях между атрибутами async и defer (англ.)
      • Руководство по JavaScript-модулям

      Found a content problem with this page?

      • Edit the page on GitHub.
      • Report the content issue.
      • View the source on GitHub.

      This page was last modified on 4 авг. 2023 г. by MDN contributors.

      Your blueprint for a better internet.

      MDN

      Support

      • Product help
      • Report an issue

      Our communities

      Developers

      • Web Technologies
      • Learn Web Development
      • MDN Plus
      • Hacks Blog
      • Website Privacy Notice
      • Cookies
      • Legal
      • Community Participation Guidelines

      Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
      Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.

      Атрибуты defer и async

      С помощью этих атрибутов можно сказать браузеру как и в каком порядке загружать скрипты.

      Время чтения: меньше 5 мин

      Открыть/закрыть навигацию по статье

      Обновлено 6 октября 2022

      Кратко

      Скопировать ссылку «Кратко» Скопировано

      Скрипты с атрибутами defer загружаются и выполняются последовательно, а с async – асинхронно. Кроме того, defer всегда ждёт, пока весь HTML-документ будет готов, а async выполняется сразу после загрузки.

      Как пишется

      Скопировать ссылку «Как пишется» Скопировано

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

      Как понять

      Скопировать ссылку «Как понять» Скопировано

      Атрибут async

      Скопировать ссылку «Атрибут async» Скопировано

      Указывает браузеру по возможности загружать скрипт асинхронно.

      Скрипт выполняется полностью асинхронно. Это означает, что файл будет выполняться без ожидания загрузки и отображения веб-страницы. При обнаружении браузер не останавливает обработку страницы, а спокойно работает дальше. Когда скрипт будет загружен – он выполнится.

       script src="script1.js" async> script> script src="script2.js" async> script>      

      Первым выполнится тот скрипт, который быстрее загрузится.

      Поддерживается всеми браузерами, кроме IE9-.

      Атрибут defer

      Скопировать ссылку «Атрибут defer» Скопировано

      Указывает браузеру что скрипт должен выполняться после разбора документа, но до события DOM Content Loaded .

      Скрипты с атрибутом defer будут предотвращать запуск события DOM Content Loaded до тех пор, пока скрипт не загрузится полностью и не завершится его инициализация.

       script src="script1.js" defer> script> script src="script2.js" defer> script>      

      Первым всегда выполнится script1 . js , который подключён раньше. Даже если script2 . js загрузится раньше, он будет выполнен после первого скрипта.

      Применение

      Скопировать ссылку «Применение» Скопировано

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

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

      Подсказки

      Скопировать ссылку «Подсказки» Скопировано

      �� Динамически вставленный (например, вставленный при помощи document . create Element ) по умолчанию загружается браузером асинхронно.

      На собеседовании

      Скопировать ссылку «На собеседовании» Скопировано

      Скопировать ссылку «Объясните разницу между script, script async и script defer.» Скопировано

      Это вопрос без ответа. Вы можете помочь! Почитайте о том, как контрибьютить в Доку.

      Атрибут defer

      Атрибут defer откладывает выполнение скрипта до тех пор, пока вся страница не будет загружена полностью.

      Синтаксис

      Значения

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

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

      HTML5 IE Cr Op Sa Fx

          Тег SCRIPT, атрибут defer    

      Введите ваш возраст

      В скрипте данного примера значение текстового поля с именем textField приравнивается 17. Однако при запуске скрипта форма еще не инициализирована, поэтому требуется использовать атрибут defer . Без него будет выведена ошибка.

      Браузеры

      В Firefox 3.6 и старше атрибут defer игнорируется, если у тега не указан атрибут src . В Firefox 3.5 поведение другое и defer работает даже для встроенных скриптов.

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

      Типы тегов

      HTML5

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

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

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

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

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

      Видео

      Документ

      Звук

      Изображения

      Объекты

      Скрипты

      Списки

      Ссылки

      Таблицы

      Текст

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

      Формы

      Фреймы

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *