W3docs

Атрибут defer в HTML

Атрибут defer в HTML указывает, что скрипт выполняется после завершения разбора страницы. Узнайте, как использовать его в элементе <script>.

Атрибут HTML defer — это boolean-атрибут элемента <script>, который указывает браузеру загружать скрипт параллельно с разбором HTML, но ждать и выполнять его только после полного завершения разбора страницы — непосредственно перед тем, как сработает событие DOMContentLoaded.

Он работает только с внешними скриптами: эффект проявляется, лишь когда присутствует атрибут src, а на встроенных скриптах (тех, чей JavaScript написан между тегами <script>) атрибут игнорируется.

Зачем нужен атрибут defer

Обычный тег <script src="..."> блокирует рендеринг. Когда парсер встречает его, он останавливает построение страницы, скачивает файл, выполняет его и только потом продолжает работу. Если скрипт находится в <head>, пользователь видит пустую страницу до тех пор, пока файл не загрузится.

Классическим обходным решением было помещать теги <script> в самый конец <body>, чтобы HTML разбирался первым. Атрибут defer делает этот приём ненужным: можно оставлять скрипты в <head> (удобно для читаемости и для того, чтобы браузер обнаруживал и загружал их раньше), при этом скрипт всё равно выполнится только после полного построения DOM. Поскольку DOM гарантированно готов, отложенные скрипты могут безопасно обращаться к элементам без необходимости оборачивать всё в обработчик DOMContentLoaded.

defer и async

Оба атрибута — defer и async — позволяют браузеру загружать скрипт в фоне, не блокируя разбор HTML. Разница состоит в том, когда и в каком порядке выполняются скрипты:

Поведениеdeferasync
Блокирует разбор HTML во время загрузкиНетНет
Когда выполняется скриптПосле завершения разбора, непосредственно перед DOMContentLoadedКак только завершится загрузка (может прервать разбор)
Порядок выполнения относительно других скриптовСохраняется — выполняется в порядке документаНе гарантируется — первым выполняется тот, что загрузится раньше
DOM гарантированно готовДаНет

Используйте defer, когда скрипты зависят от DOM или друг от друга (порядок важен). Используйте async для независимых, самодостаточных скриптов — например, аналитики или рекламных тегов, — где порядок не имеет значения и каждый должен выполняться сразу по прибытии.

Если не указан ни async, ни defer, скрипт загружается и выполняется немедленно, блокируя парсер в этой точке.

В HTML 4.01 поведение defer зависело от реализации, тогда как HTML5 стандартизировал его. В XHTML атрибут defer необходимо записывать как <script defer="defer">, поскольку сокращённая запись атрибутов запрещена.

Синтаксис

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

Пример атрибута defer в HTML

Скрипт ниже помещён в <head>, однако благодаря отложенному выполнению он запускается лишь после того, как абзац появится в DOM, — поэтому document.getElementById находит его:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"
      defer
    ></script>
    <noscript>Sorry, your browser doesn't support JavaScript!</noscript>
  </head>
  <body>
    <h1>Example</h1>
    <p id="demo">Waiting for the deferred script...</p>
    <script defer>
      // This deferred external script (jQuery) is already loaded,
      // and the DOM is fully parsed, so the line below works.
      document.getElementById("demo").textContent =
        "jQuery version " + jQuery.fn.jquery + " ran after parsing.";
    </script>
  </body>
</html>

Примечание: атрибут defer у встроенного тега <script> выше игнорируется — встроенные скрипты всегда выполняются на месте. Здесь всё работает лишь потому, что этот тег стоит последним и отложенный внешний скрипт уже загружен. Чтобы гарантировать, что отложенная внешняя библиотека загрузится раньше вашего собственного кода, перенесите свой код тоже в отдельный внешний файл с defer, поскольку отложенные скрипты выполняются в порядке документа.

Практика

Практика
Как правильно использовать атрибут 'defer' в HTML?
Как правильно использовать атрибут 'defer' в HTML?
Was this page helpful?