\n\n\n

Заголовок

\n \n \n\n\n```\n\n**Порядок выполнения:**\n1. Браузер начинает парсить HTML\n2. Встречает `\n \n \n\n```\n\n**Особенности async:**\n- Загрузка происходит параллельно с парсингом HTML\n- Скрипт выполняется как только загружен (порядок не гарантирован)\n- Не подходит для скриптов, зависимых друг от друга\n\n```javascript\n// Если у вас есть две библиотеки:\n\n // Может выполниться раньше jQuery!\n```\n\n### 3. Отложенная загрузка (defer)\n\nАтрибут **defer** загружает скрипт асинхронно, но гарантирует выполнение в порядке следования в HTML.\n\n```html\n\n

Контент страницы

\n

Загружается без задержек

\n \n \n \n \n \n\n```\n\n**Особенности defer:**\n- Загрузка происходит в фоне\n- Выполнение гарантировано в порядке следования\n- Событие `DOMContentLoaded` срабатывает после всех defer скриптов\n- Идеален для большинства случаев\n\n## Наглядное сравнение\n\n```\nСинхронная загрузка (без атрибутов):\n|--parsing HTML--|\n |--fetching script1.js--|\n |--execute script1.js--|\n |--parsing HTML continues--|\n\nАсинхронная загрузка (async):\n|--parsing HTML--|\n |--fetching script1.js in background--|\n|--parsing continues--|\n |--execute script1.js when ready--|\n\nОтложенная загрузка (defer):\n|--parsing HTML--|\n |--fetching script1.js in background--|\n|--parsing continues--|\n |--execute script1.js--|\n```\n\n## Практические примеры\n\n### Плохо: Синхронная загрузка в head\n\n```html\n\n \n \n\n\n \n\n```\n\n**Проблема:** пользователь видит белую страницу, пока загружаются скрипты.\n\n### Хорошо: Отложенная загрузка в body\n\n```html\n\n
Заголовок
\n
Основной контент
\n \n \n \n \n \n\n```\n\n**Преимущество:** контент отображается быстро, скрипты загружаются параллельно.\n\n### Специальный случай: Аналитика (async)\n\n```html\n\n \n \n\n```\n\n**Почему async:** аналитика не критична для работы сайта, может загружаться независимо.\n\n## Встроенные скрипты\n\nВстроенный JavaScript также выполняется синхронно по умолчанию:\n\n```html\n\n

Заголовок

\n```\n\n## Современные подходы\n\n### 1. Module Scripts\n\n```html\n\n\n```\n\n### 2. Dynamic Script Loading\n\n```javascript\nconst script = document.createElement('script');\nscript.src = 'app.js';\nscript.async = true; // или false для синхронной\ndocument.body.appendChild(script);\n\nscript.onload = () => {\n console.log('Script loaded');\n};\n```\n\n### 3. Promise-based Loading\n\n```javascript\nconst loadScript = (src) => {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = src;\n script.onload = resolve;\n script.onerror = reject;\n document.body.appendChild(script);\n });\n};\n\n// Использование\nawait loadScript('app.js');\nconsole.log('Script loaded!');\n```\n\n## Рекомендации\n\n**Используй defer для:**\n- Основных скриптов приложения\n- Скриптов, зависимых друг от друга\n- Скриптов, работающих с DOM\n\n**Используй async для:**\n- Независимых скриптов (аналитика, реклама)\n- Нетривиальных библиотек\n\n**Избегай синхронной загрузки:**\n- Она замораживает страницу\n- Ухудшает пользовательский опыт\n- Современные браузеры предупреждают об этом\n\n## Вывод\n\nСкрипты не всегда загружаются синхронно. По умолчанию они **блокирующие**, но с атрибутами **async** и **defer** вы можете управлять загрузкой для оптимизации производительности страницы. В современных приложениях используй **defer** как стандарт для лучшего пользовательского опыта.","dateCreated":"2026-04-02T22:07:32.414299","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Всегда ли загружаются скрипты синхронно

1.0 Junior🔥 241 комментариев
#JavaScript Core#Браузер и сетевые технологии

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

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

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

Синхронная и асинхронная загрузка скриптов

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

Способы загрузки скриптов

1. Синхронная загрузка (по умолчанию)

Когда вы используете обычный тег <script>, браузер загружает и выполняет скрипт синхронно. Это блокирует парсинг HTML до полного выполнения скрипта.

<!DOCTYPE html>
<html>
<head>
  <!-- Скрипт в head блокирует загрузку страницы -->
  <script src="script.js"></script>
</head>
<body>
  <h1>Заголовок</h1>
  <!-- Браузер сначала загружает script.js, потом парсит это содержимое -->
  <script src="app.js"></script> <!-- Синхронная загрузка -->
</body>
</html>

Порядок выполнения:

  1. Браузер начинает парсить HTML
  2. Встречает <script src="app.js">
  3. Загружает и выполняет app.js
  4. Только потом продолжает парсить остальной HTML

2. Асинхронная загрузка (async)

Атрибут async позволяет загружать скрипт в фоне без блокировки парсинга HTML.

<body>
  <h1>Контент страницы</h1>
  <p>Этот текст загружается первым</p>
  
  <!-- Загружается асинхронно -->
  <script async src="analytics.js"></script>
  
  <!-- Парсинг продолжается без ожидания analytics.js -->
</body>

Особенности async:

  • Загрузка происходит параллельно с парсингом HTML
  • Скрипт выполняется как только загружен (порядок не гарантирован)
  • Не подходит для скриптов, зависимых друг от друга
// Если у вас есть две библиотеки:
<script async src="jquery.js"></script>
<script async src="my-app.js"></script> // Может выполниться раньше jQuery!

3. Отложенная загрузка (defer)

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

<body>
  <h1>Контент страницы</h1>
  <p>Загружается без задержек</p>
  
  <!-- Загружается асинхронно, но выполняется в порядке -->
  <script defer src="jquery.js"></script>
  <script defer src="my-app.js"></script>
  <!-- my-app.js выполнится ПОСЛЕ jQuery -->
</body>

Особенности defer:

  • Загрузка происходит в фоне
  • Выполнение гарантировано в порядке следования
  • Событие DOMContentLoaded срабатывает после всех defer скриптов
  • Идеален для большинства случаев

Наглядное сравнение

Синхронная загрузка (без атрибутов):
|--parsing HTML--|
                 |--fetching script1.js--|
                                         |--execute script1.js--|
                                                                 |--parsing HTML continues--|

Асинхронная загрузка (async):
|--parsing HTML--|
                 |--fetching script1.js in background--|
|--parsing continues--|
                        |--execute script1.js when ready--|

Отложенная загрузка (defer):
|--parsing HTML--|
                 |--fetching script1.js in background--|
|--parsing continues--|
                       |--execute script1.js--|

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

Плохо: Синхронная загрузка в head

<head>
  <script src="large-library.js"></script> <!-- Блокирует всё -->
  <script src="another-script.js"></script> <!-- Ждет первого -->
</head>
<body>
  <!-- Пользователь видит белую страницу -->
</body>

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

Хорошо: Отложенная загрузка в body

<body>
  <header>Заголовок</header>
  <main>Основной контент</main>
  <footer>Подвал</footer>
  
  <!-- Скрипты загружаются в фоне, но выполняются после парсинга -->
  <script defer src="jquery.js"></script>
  <script defer src="app.js"></script>
</body>

Преимущество: контент отображается быстро, скрипты загружаются параллельно.

Специальный случай: Аналитика (async)

<head>
  <!-- Google Analytics - не критична для функционала -->
  <script async src="https://www.googletagmanager.com/gtag/js"></script>
</head>

Почему async: аналитика не критична для работы сайта, может загружаться независимо.

Встроенные скрипты

Встроенный JavaScript также выполняется синхронно по умолчанию:

<script>
  console.log("Выполняется синхронно");
  console.log(document.querySelector("h1")); // null - элемент ещё не загружен
</script>
<h1>Заголовок</h1>

Современные подходы

1. Module Scripts

<!-- ES6 модули загружаются асинхронно по умолчанию -->
<script type="module" src="app.js"></script>

2. Dynamic Script Loading

const script = document.createElement('script');
script.src = 'app.js';
script.async = true; // или false для синхронной
document.body.appendChild(script);

script.onload = () => {
  console.log('Script loaded');
};

3. Promise-based Loading

const loadScript = (src) => {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = src;
    script.onload = resolve;
    script.onerror = reject;
    document.body.appendChild(script);
  });
};

// Использование
await loadScript('app.js');
console.log('Script loaded!');

Рекомендации

Используй defer для:

  • Основных скриптов приложения
  • Скриптов, зависимых друг от друга
  • Скриптов, работающих с DOM

Используй async для:

  • Независимых скриптов (аналитика, реклама)
  • Нетривиальных библиотек

Избегай синхронной загрузки:

  • Она замораживает страницу
  • Ухудшает пользовательский опыт
  • Современные браузеры предупреждают об этом

Вывод

Скрипты не всегда загружаются синхронно. По умолчанию они блокирующие, но с атрибутами async и defer вы можете управлять загрузкой для оптимизации производительности страницы. В современных приложениях используй defer как стандарт для лучшего пользовательского опыта.

Всегда ли загружаются скрипты синхронно | PrepBro