\n \n```\n\nПравильное решение — всем связанным скриптам добавить `defer`:\n```html\n\n\n\n```\n\n### 3. Скрипты, использующие `document.write()`\n**`document.write()` категорически несовместим с `defer` (и с `async`)**. В отложенных скриптах `document.write()` может полностью очистить документ или вызвать ошибку, так как парсинг HTML уже завершён.\n\n```html\n\n\n```\n\n### 4. Скрипты, которым нужен полный доступ к DOM до события `DOMContentLoaded`\nСкрипты с `defer` выполняются **перед** событием `DOMContentLoaded`. Однако если вашему скрипту нужна **полная** готовность DOM, включая стили, изображения и т.д., лучше использовать событие `load` или разместить скрипт в конце ``.\n\n```javascript\n// Если этот код в defer-скрипте, он выполнится ДО загрузки изображений\nwindow.addEventListener('load', function() {\n console.log('Все ресурсы загружены'); // Это событие ещё не наступило\n});\n```\n\n### 5. Очень маленькие или инлайновые скрипты\nДля небольших инлайновых скриптов (менее 1 КБ), которые не требуют отдельного HTTP-запроса, использование `defer` не имеет смысла. Их лучше встроить прямо в место использования для минимальной задержки.\n\n```html\n\n\n```\n\n### 6. Скрипты, динамически добавляемые через JavaScript\nАтрибут `defer` работает только для **статически объявленных** в HTML скриптах. Для динамически созданных тегов ` \n\n\n\n\n\n\n```\n\n**Главный принцип**: `defer` — это инструмент для **некритических скриптов**, которые могут подождать до полного парсинга HTML. Для всего, что должно работать \"здесь и сейчас\", используйте стандартное подключение или инлайновое выполнение.","dateCreated":"2026-04-04T22:18:27.246637","upvoteCount":0,"author":{"@type":"Person","name":"deepseek-v3.2"}}}}
← Назад к вопросам

Когда нельзя использовать defer?

1.7 Middle🔥 161 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Когда атрибут defer не следует использовать

Атрибут defer у тега <script> — мощный инструмент для оптимизации загрузки страницы, но его применение имеет ряд важных ограничений. Вот ключевые ситуации, когда его использование нежелательно или невозможно.

1. Скрипты, критичные для отрисовки содержимого (Render-Blocking)

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

  • Модифицирует DOM до её отображения.
  • Загружает полифиллы для старых браузеров, без которых дальнейшая работа невозможна.
  • Выполняет критически важные вычисления для начального рендера.

Такие скрипты лучше размещать в <head> без defer и async, либо встроить непосредственно в разметку.

2. Скрипты, зависящие от других скриптов без defer

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

<!-- ПЛОХО: script2 зависит от script1, но порядок не гарантирован -->
<script src="library.js"></script> <!-- БЕЗ defer -->
<script src="app.js" defer></script> <!-- Может выполниться ДО library.js -->

Правильное решение — всем связанным скриптам добавить defer:

<!-- ХОРОШО: порядок сохранён -->
<script src="library.js" defer></script>
<script src="app.js" defer></script>

3. Скрипты, использующие document.write()

document.write() категорически несовместим с defer (и с async). В отложенных скриптах document.write() может полностью очистить документ или вызвать ошибку, так как парсинг HTML уже завершён.

<!-- ОПАСНО: может сломать страницу -->
<script defer>
  document.write("<div>Новый контент</div>"); // Непредсказуемое поведение!
</script>

4. Скрипты, которым нужен полный доступ к DOM до события DOMContentLoaded

Скрипты с defer выполняются перед событием DOMContentLoaded. Однако если вашему скрипту нужна полная готовность DOM, включая стили, изображения и т.д., лучше использовать событие load или разместить скрипт в конце <body>.

// Если этот код в defer-скрипте, он выполнится ДО загрузки изображений
window.addEventListener('load', function() {
  console.log('Все ресурсы загружены'); // Это событие ещё не наступило
});

5. Очень маленькие или инлайновые скрипты

Для небольших инлайновых скриптов (менее 1 КБ), которые не требуют отдельного HTTP-запроса, использование defer не имеет смысла. Их лучше встроить прямо в место использования для минимальной задержки.

<!-- Нет смысла в defer для инлайнового кода -->
<script>
  // Инициализация, которая должна сработать сразу
  window.initialState = { user: 'admin' };
</script>

6. Скрипты, динамически добавляемые через JavaScript

Атрибут defer работает только для статически объявленных в HTML скриптах. Для динамически созданных тегов <script> атрибут defer по умолчанию игнорируется в большинстве браузеров.

// defer здесь не сработает как ожидается
const script = document.createElement('script');
script.src = 'dynamic.js';
script.defer = true; // Не даёт эффекта отложенного выполнения
document.head.appendChild(script);

7. Ситуации, требующие максимальной совместимости со старыми браузерами

Хотя defer поддерживается давно (с IE10), в очень старых окружениях (IE9 и ранее) он может работать некорректно. Если требуется поддержка древних браузеров, лучше использовать традиционное размещение скриптов в конце <body>.

Альтернативы и рекомендации

  • Используйте async для независимых скриптов (например, счётчики аналитики), где порядок не важен.
  • Комбинируйте подходы: критические скрипты — без атрибутов, второстепенные — с defer, сторонние — с async.
  • Модули ES6 (<script type="module">) по умолчанию ведут себя как defer, но с дополнительными возможностями.
<!-- Современный подход с модулями -->
<script type="module" src="main.js"></script> <!-- Выполнится как defer -->

<!-- Классический defer для легаси-скриптов -->
<script src="legacy.js" defer></script>

<!-- Async для независимых ресурсов -->
<script async src="analytics.js"></script>

Главный принцип: defer — это инструмент для некритических скриптов, которые могут подождать до полного парсинга HTML. Для всего, что должно работать "здесь и сейчас", используйте стандартное подключение или инлайновое выполнение.