Defer

Материал из Энциклопедия интернет-маркетинга MarketWiki

Defer (от англ. defer - откладывать) - это атрибут HTML-тега <script>, который указывает браузеру загружать JavaScript-файл асинхронно, но выполнять его только после полной загрузки и разбора (парсинга) HTML-документа. Использование defer позволяет не блокировать рендеринг страницы, улучшая метрики FCP (First Contentful Paint) и LCP (Largest Contentful Paint).

Для маркетолога атрибут defer важен в том, как он способствует оптимизации скорости загрузки сайта, так как правильно настроенная загрузка JavaScript напрямую влияет на Core Web Vitals и, следовательно, на позиции в поисковой выдаче и конверсию.

Проблема блокировки рендеринга

[править]

Когда браузер загружает HTML-страницу и встречает обычный тег <script src="script.js"> без атрибутов, он:

  1. Останавливает дальнейший парсинг (разбор) HTML
  2. Загружает указанный JavaScript-файл
  3. Выполняет его
  4. Только после этого продолжает парсить HTML

Это называется синхронной (блокирующей) загрузкой скриптов.

Последствия для пользователя:

  • Пользователь видит пустой экран дольше необходимого
  • Основной контент отображается с задержкой
  • Ухудшаются метрики FCP и LCP
  • Увеличивается показатель отказов

Как работает defer

[править]

Атрибут defer меняет поведение браузера:

<script src="script.js" defer></script>
Этапы работы defer
Этап Что происходит
1. Парсинг HTML Браузер продолжает парсить HTML без остановки, скрипт загружается в фоне
2. Загрузка скрипта Скрипт загружается параллельно с парсингом HTML
3. Выполнение Скрипт выполняется только после полного парсинга HTML-документа
4. Порядок Несколько скриптов с defer выполняются в том порядке, в котором они объявлены в коде

Сравнение defer, async и обычной загрузки

[править]
Сравнение способов загрузки скриптов
Тип загрузки Парсинг HTML Загрузка скрипта Выполнение
Обычный (без атрибутов) Блокируется Немедленно, блокирует парсинг Немедленно после загрузки
async Не блокируется Параллельно с парсингом Немедленно после загрузки (может блокировать парсинг)
defer Не блокируется Параллельно с парсингом После полного парсинга HTML
<!-- Обычная загрузка - блокирует рендеринг -->
<script src="sync.js"></script>

<!-- Async - загружается параллельно, выполняется сразу после загрузки -->
<script src="async.js" async></script>

<!-- Defer - загружается параллельно, выполняется после загрузки HTML -->
<script src="defer.js" defer></script>

Визуальная схема работы

[править]

Обычная загрузка:

[HTML парсинг] [Загрузка и выполнение скрипта] [HTML парсинг продолжается]
     ↓                      ↓                              ↓
Пользователь видит пустой экран → Контент появляется с задержкой

Defer:

[HTML парсинг] [HTML парсинг] [HTML парсинг] → [Выполнение скрипта]
      ↓              ↓              ↓                    ↓
 Загрузка скрипта в фоне → Пользователь видит контент быстрее

Когда использовать defer

[править]
Сценарии использования defer
Сценарий Рекомендация
Скрипты, которые зависят от DOM Использовать defer - гарантирует, что DOM уже загружен
Скрипты с зависимостями Использовать defer - сохраняется порядок выполнения
Скрипты, не критичные для первого экрана Использовать defer - не блокируют рендеринг
Скрипты аналитики (сбор данных) Использовать defer или async - не блокируют пользователя

Когда НЕ использовать defer

[править]
Сценарии, где defer не подходит
Сценарий Причина
Скрипты, критичные для первого экрана Если скрипт нужен для отображения основного контента, лучше встроить его напрямую (inline)
Очень маленькие скрипты Накладные расходы на асинхронную загрузку могут превышать выгоду
Скрипты, которые должны выполниться до парсинга Например, модификация DOM до того, как пользователь увидит страницу

Инструменты для анализа загрузки скриптов

[править]
Инструменты диагностики
Инструмент Назначение
Chrome DevTools (Network) Отображает загрузку скриптов и их влияние на рендеринг
Lighthouse Аудит, предупреждающий о блокирующих рендеринг скриптах
WebPageTest Детальный анализ загрузки ресурсов на реальных устройствах

Пример оптимизации

[править]

До оптимизации:

<head>
  <script src="jquery.js"></script>     <!-- блокирует рендеринг -->
  <script src="analytics.js"></script>  <!-- блокирует рендеринг -->
  <script src="app.js"></script>        <!-- блокирует рендеринг -->
</head>

После оптимизации:

<head>
  <!-- Критический inline-скрипт для первого экрана -->
  <script>/* критический код */</script>
  
  <!-- Не критические скрипты с defer -->
  <script src="jquery.js" defer></script>
  <script src="analytics.js" defer></script>
  <script src="app.js" defer></script>
</head>

Влияние на Core Web Vitals

[править]
Влияние defer на метрики Core Web Vitals
Метрика Как влияет defer
FCP (First Contentful Paint) Улучшается - браузер не ждёт скрипты для отображения первого контента
LCP (Largest Contentful Paint) Улучшается - основной контент загружается быстрее
INP (Interaction to Next Paint) Defer позволяет основному потоку быстрее обрабатывать пользовательские взаимодействия, снижая задержку реакции на клики и нажатия клавиш

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

[править]

Атрибут defer поддерживается всеми современными браузерами:

  • Google Chrome - с версии 1.0
  • Mozilla Firefox - с версии 3.5
  • Safari - с версии 5.0
  • Microsoft Edge - с версии 12
  • Internet Explorer - с версии 10

Связь с другими техниками оптимизации

[править]
Взаимодействие defer с другими техниками
Техника Взаимодействие с defer
Critical CSS Дополняют друг друга - CSS не блокирует рендеринг, скрипты тоже не блокируют
Code Splitting Разделённые чанки можно загружать с defer
Preload Можно использовать preload для важных скриптов, а defer для некритичных

Связанные термины

[править]