\n\n\n

Заголовок

\n

Текст

\n \n\n\n```\n\nЭто приводит к задержке отрисовки страницы и плохому пользовательскому опыту.\n\n### Три способа подключения скриптов\n\n**1. Синхронный (по умолчанию) — ХУДШИЙ**\n\n```html\n\n\n\n```\n\n```javascript\n// Пример бесполезной блокировки\n\n\n```\n\n**2. Атрибут async — ЛУЧШЕ для неполностью зависимых скриптов**\n\n```html\n\n\n\n```\n\n**3. Атрибут defer — ЛУЧШЕ для зависимых скриптов**\n\n```html\n\n\n\n```\n\n### Сравнительная таблица\n\n```html\n\n\n\n\n\n\n\n\n\n\n\n```\n\n### Когда использовать async\n\n**Async подходит для независимых скриптов:**\n\n```html\n\n\n\n\n\n\n\n\n\n```\n\nЭти скрипты:\n- Не зависят от других скриптов\n- Не влияют на функциональность страницы\n- Могут быть выполнены в любое время\n\n### Когда использовать defer\n\n**Defer подходит для основной логики:**\n\n```html\n\n\n
\n \n \n \n\n\n\n\n\n\n```\n\n### Практические примеры\n\n**Пример 1: Next.js или современный фронтенд**\n\n```html\n\n\n```\n\n**Пример 2: Комбинированный подход (Production)**\n\n```html\n\n\n\n PrepBro\n \n \n \n\n\n
\n \n \n \n \n \n \n \n \n \n \n\n\n```\n\n### Ошибки с async\n\n**Ошибка 1: Неправильный порядок выполнения**\n\n```html\n\n\n\n\n```\n\n**Правильно:**\n```html\n\n\n\n```\n\n**Ошибка 2: Документ в async скрипте может быть неполным**\n\n```javascript\n// script.js с атрибутом async\nconst mainContent = document.getElementById('main');\n// mainContent может быть null если скрипт выполнился до парсинга!\n```\n\n**Правильно:**\n```javascript\ndocument.addEventListener('DOMContentLoaded', () => {\n const mainContent = document.getElementById('main');\n // Теперь mainContent точно существует\n});\n```\n\n### Module скрипты\n\nС ES modules поведение меняется:\n\n```html\n\n\n\n\n\n\n```\n\n### Инструменты для анализа\n\n```javascript\n// Lighthouse (DevTools) показывает время загрузки\n// Предлагает оптимизации:\n// - Перенести скрипты с async на defer\n// - Отложить загрузку третьих сервисов\n// - Использовать Web Workers\n\n// Проверить в DevTools\nPerformance -> Performance tab\n// Увидите синюю линию (парсинг HTML)\n// И фиолетовую (выполнение скриптов)\n```\n\n### Итог\n\n**Правило выбора:**\n\n1. **defer** — используй ПО УМОЛЧАНИЮ для своих скриптов\n ```html\n \n ```\n\n2. **async** — только для полностью независимых скриптов\n ```html\n \n ```\n\n3. **Ничего** — ПОЧТИ НИКОГДА (очень редко для критичного inline скрипта)\n ```html\n \n ```\n\n**Главный вывод:** `async` и `defer` делают загрузку страницы быстрее. Используй `defer` для своих скриптов, `async` для третьих сервисов.","dateCreated":"2026-04-02T21:49:39.946121","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Что такое атрибут async у скрипта?

1.0 Junior🔥 182 комментариев
#HTML и CSS#Браузер и сетевые технологии

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

Что такое атрибут async у скрипта

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

Проблема, которую решает async

По умолчанию при парсинге HTML браузер блокирует отрисовку при встречи <script>:

<!DOCTYPE html>
<html>
<head>
  <title>Моя страница</title>
  <script src="./large-library.js"></script>
</head>
<body>
  <h1>Заголовок</h1>
  <p>Текст</p>
  <!-- 
    Парсинг HTML блокируется:
    1. Браузер ждет загрузку large-library.js
    2. Парсит и выполняет скрипт
    3. Только потом отрисовывает страницу
    4. Пользователь видит белый экран!
  -->
</body>
</html>

Это приводит к задержке отрисовки страницы и плохому пользовательскому опыту.

Три способа подключения скриптов

1. Синхронный (по умолчанию) — ХУДШИЙ

<script src="./large-library.js"></script>

<!-- 
Порядок выполнения:
1. Парсинг HTML: ════════════════
   │
   ├─ Встречена загрузка скрипта
   │
2. Загрузка скрипта: ════════════════
   │
   └─ Блокирует парсинг HTML!

3. Выполнение скрипта: ════════════════
4. Продолжение парсинга HTML

Время до первой отрисовки: ДОЛГО
-->
// Пример бесполезной блокировки
<script src="./analytics.js"></script>
<!-- analytics.js не критичен, но блокирует загрузку страницы! -->

2. Атрибут async — ЛУЧШЕ для неполностью зависимых скриптов

<script src="./analytics.js" async></script>

<!-- 
Порядок выполнения:
1. Парсинг HTML: ════════════════════════════════════════
   │                                   ^
   ├─ Встречена загрузка скрипта       │
   │  (загружается параллельно!)        │
   │                                   │
2. Загрузка скрипта:    ════════════════
   │                   │
   │ (НЕ блокирует)    │
   │                   ↓
3. Парсинг продолжается ════════════════
   │                    ^
   │                    │
   └──────────────────────→ Когда скрипт загруженТОЧнуТ

4. Выполнение скрипта (когда загрузился)

Время до первой отрисовки: КОРОЧЕ
-->

3. Атрибут defer — ЛУЧШЕ для зависимых скриптов

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

<!-- 
Порядок выполнения:
1. Парсинг HTML: ════════════════════════════════════════════════
   │                                                            ^
   ├─ Встречена загрузка скрипта                               │
   │  (загружается параллельно!)                               │
   │                                                            │
2. Загрузка скрипта:    ════════════════                        │
   │                   │                                        │
   │ (НЕ блокирует)    │                                        │
   │                   │                                        │
3. Парсинг продолжается ════════════════════════════════════════
                                                                │
4. Парсинг окончен ◄─────────────────────────────────────────────┘

5. Выполнение скрипта (ПОСЛЕ парсинга)

Время до первой отрисовки: ОЧЕНЬ КОРОЧЕ
-->

Сравнительная таблица

<!-- Синхронный (без атрибутов) -->
<script src="app.js"></script>
<!-- 
  Загрузка: блокирует парсинг
  Выполнение: блокирует парсинг
  Порядок: гарантирован (если несколько скриптов)
  Использование: практически НИКОГДА
-->

<!-- async -->
<script src="analytics.js" async></script>
<!-- 
  Загрузка: параллельно парсингу
  Выполнение: как только загрузился (может быть до/после парсинга)
  Порядок: НЕ гарантирован
  Использование: отдельные, независимые скрипты (Google Analytics, ads)
-->

<!-- defer -->
<script src="app.js" defer></script>
<!-- 
  Загрузка: параллельно парсингу
  Выполнение: после полного парсинга HTML
  Порядок: гарантирован (выполняются в порядке указания)
  Использование: основные скрипты приложения
-->

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

Async подходит для независимых скриптов:

<!-- Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag() { dataLayer.push(arguments); }
  gtag('js', new Date());
  gtag('config', 'GA_ID');
</script>

<!-- Реклама -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

<!-- Tracking -->
<script async src="https://api.example.com/tracking.js"></script>

Эти скрипты:

  • Не зависят от других скриптов
  • Не влияют на функциональность страницы
  • Могут быть выполнены в любое время

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

Defer подходит для основной логики:

<!-- React приложение -->
<body>
  <div id="root"></div>
  
  <!-- defer гарантирует, что скрипт выполнится после парсинга HTML -->
  <script src="./bundle.js" defer></script>
</body>

<!-- Несколько скриптов с зависимостями -->
<script src="./jquery.js" defer></script>
<script src="./jquery-plugin.js" defer></script>
<!-- Выполняются в порядке указания -->

Практические примеры

Пример 1: Next.js или современный фронтенд

<!-- Next.js автоматически добавляет defer -->
<script src="/_next/static/chunks/main.js" defer></script>

Пример 2: Комбинированный подход (Production)

<!DOCTYPE html>
<html>
<head>
  <title>PrepBro</title>
  
  <!-- Критичные стили -->
  <style>/* критичный CSS inline */</style>
</head>
<body>
  <div id="root"></div>
  
  <!-- Основное приложение - defer -->
  <script src="./app.bundle.js" defer></script>
  
  <!-- Analytics - async (независим) -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=GA_ID"></script>
  <script async>
    // Analytics код
  </script>
  
  <!-- Сторонние сервисы - async -->
  <script async src="https://cdn.example.com/tracking.js"></script>
</body>
</html>

Ошибки с async

Ошибка 1: Неправильный порядок выполнения

<!-- Опасно! -->
<script src="./jquery.js" async></script>
<script src="./jquery-plugin.js" async></script>
<!-- 
  jquery-plugin может выполниться ДО jquery!
  jQuery Plugin не найдет объект jQuery
-->

Правильно:

<!-- Используем defer для зависимостей -->
<script src="./jquery.js" defer></script>
<script src="./jquery-plugin.js" defer></script>

Ошибка 2: Документ в async скрипте может быть неполным

// script.js с атрибутом async
const mainContent = document.getElementById('main');
// mainContent может быть null если скрипт выполнился до парсинга!

Правильно:

document.addEventListener('DOMContentLoaded', () => {
  const mainContent = document.getElementById('main');
  // Теперь mainContent точно существует
});

Module скрипты

С ES modules поведение меняется:

<!-- 
  Модули загружаются паралелльно
  Выполняются в порядке указания (как defer)
-->
<script type="module" src="./main.js"></script>
<script type="module" src="./app.js"></script>

<!-- 
  async модули выполняются как скоро загрузились
  (порядок не гарантирован)
-->
<script type="module" async src="./analytics.js"></script>

Инструменты для анализа

// Lighthouse (DevTools) показывает время загрузки
// Предлагает оптимизации:
// - Перенести скрипты с async на defer
// - Отложить загрузку третьих сервисов
// - Использовать Web Workers

// Проверить в DevTools
Performance -> Performance tab
// Увидите синюю линию (парсинг HTML)
// И фиолетовую (выполнение скриптов)

Итог

Правило выбора:

  1. defer — используй ПО УМОЛЧАНИЮ для своих скриптов

    <script src="./app.js" defer></script>
    
  2. async — только для полностью независимых скриптов

    <script src="https://api.analytics.com/track.js" async></script>
    
  3. Ничего — ПОЧТИ НИКОГДА (очень редко для критичного inline скрипта)

    <script>console.log('ASAP');</script>
    

Главный вывод: async и defer делают загрузку страницы быстрее. Используй defer для своих скриптов, async для третьих сервисов.