\n\n\n```\n\n#### Проблемы размещения в \n\n```html\n\n\n \n\n\n

Контент

\n\n```\n\nБраузер блокирует парсинг HTML при встрече с `\n \n\n\n```\n\n### 3. Детальное объяснение: почему CSS в \n\n```html\n\n\n \n \n\n\n

Заголовок

\n\n```\n\n```html\n\n\n

Заголовок

\n \n \n \n\n```\n\n**FOUC (Flash of Unstyled Content)** - когда содержимое сначала видно без стилей, а потом применяются стили. Это плохой UX.\n\n### 4. Детальное объяснение: почему скрипты внизу\n\n#### Без атрибутов (синхронные)\n\n```html\n\n\n \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

Контент

\n\n\n\n\n\n\n```\n\nПроблема: скрипты выполняются в случайном порядке! Если script2 зависит от script1 - будет ошибка.\n\n#### С атрибутом defer\n\n```html\n\n\n \n \n\n\n

Контент

\n\n\n\n\n\n\n```\n\nЭто лучшее решение для большинства случаев!\n\n### 5. Практические рекомендации\n\n#### Современный подход (Next.js / React)\n\n```html\n\n\n\n \n \n \n My App\n \n \n \n \n \n \n \n\n\n
\n \n \n \n\n\n```\n\n#### Для внешних скриптов (Google Analytics, Sentry)\n\n```html\n\n \n \n \n\n\n \n\n```\n\nЭти скрипты не критичны и можно загружать параллельно.\n\n### 6. Сравнение разных подходов\n\n```javascript\n// Временная диаграмма загрузки страницы\n\n// ПЛОХО: синхронный скрипт в \nCSS: [==================]\nHTML: [======X ]\n HTML блокирован скриптом\nScript: [=========]\nОбщее время: ~3 секунды\n\n// ЛУЧШЕ: async скрипты в \nCSS: [==================]\nHTML: [====================] Парсинг не прерывается\nScript1: [=======]\nScript2: [========]\nОбщее время: ~2 секунды\n\n// ЛУЧШЕ ВСЕГО: defer скрипты в + CSS\nCSS: [==================]\nHTML: [====================] Парсинг не прерывается\nScript1: [=======]\nScript2: [========]\nОбщее время: ~2.2 секунды\n Скрипты выполняются в правильном порядке\n```\n\n### 7. Специальные случаи\n\n#### Inline скрипты\n\n```html\n\n\n \n \n\n```\n\n#### Загрузка скриптов динамически\n\n```javascript\n// Загрузить скрипт после загрузки страницы\nfunction loadScript(src) {\n const script = document.createElement('script');\n script.src = src;\n script.async = true;\n document.head.appendChild(script);\n}\n\n// После того как DOM готов\nwindow.addEventListener('DOMContentLoaded', () => {\n loadScript('/heavy-feature.js');\n});\n```\n\n#### Предзагрузка vs Prefetch\n\n```html\n\n\n \n \n\n\n\n\n \n \n\n```\n\n### 8. Core Web Vitals и производительность\n\n```html\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n\n\n \n\n\n```\n\n### Чеклист оптимизации\n\n- CSS в `` - всегда\n- Скрипты внизу `` или в `` с `defer`\n- Используй `async` только для независимых скриптов\n- Используй `preload` для критичных ресурсов\n- Минимизируй inline скрипты в ``\n- Избегай FOUC (Flash of Unstyled Content)\n- Проверяй загрузку с помощью DevTools Performance\n\n### Заключение\n\nПорядок и размещение `` и `
← Назад к вопросам

Есть ли разница в каком порядке указывать теги link и script?

1.0 Junior🔥 121 комментариев
#JavaScript Core

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

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

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

Порядок тегов <link> и <script> в HTML

Да, порядок размещения тегов <link> и <script> в HTML имеет БОЛЬШОЕ значение для производительности, пользовательского опыта и правильной работы приложения. Это критичный аспект frontend оптимизации.

1. Место размещения тегов

В <head>

<!DOCTYPE html>
<html>
<head>
  <!-- CSS загружается ЗДЕСЬ -->
  <link rel="stylesheet" href="/styles.css">
  <!-- Блокирующие ресурсы! -->
</head>
<body>
  <h1>Контент</h1>
  
  <!-- JavaScript загружается ЗДЕСЬ -->
  <script src="/script.js"></script>
</body>
</html>

Проблемы размещения в <head>

<!-- ПЛОХО: Блокирующие скрипты в <head> -->
<head>
  <script src="/heavy-script.js"></script> <!-- Браузер ждёт загрузки и выполнения -->
</head>
<body>
  <h1>Контент</h1> <!-- Этот HTML не отображается до выполнения скрипта! -->
</body>

Браузер блокирует парсинг HTML при встрече с <script> в <head>. Это плохо для UX.

2. Правильный порядок и размещение

Best Practice

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My App</title>
  
  <!-- 1. CSS: ВСЕГДА в <head> -->
  <link rel="stylesheet" href="/styles.css">
  <link rel="stylesheet" href="/theme.css">
  
  <!-- 2. Preload критичных ресурсов -->
  <link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
</head>
<body>
  <div id="root">Loading...</div>
  
  <!-- 3. Скрипты: внизу перед </body> -->
  <script src="/bundle.js"></script>
  <script src="/analytics.js"></script>
</body>
</html>

3. Детальное объяснение: почему CSS в <head>

<!-- ПРАВИЛЬНО: CSS в <head> -->
<head>
  <link rel="stylesheet" href="/styles.css">
  <!-- Браузер загружает CSS параллельно -->
</head>
<body>
  <h1>Заголовок</h1> <!-- Стилизирован корректно с самого начала -->
</body>
<!-- НЕПРАВИЛЬНО: CSS в конце <body> -->
<body>
  <h1>Заголовок</h1> <!-- Сначала отображается без стилей (FOUC - Flash of Unstyled Content) -->
  
  <link rel="stylesheet" href="/styles.css"> <!-- Потом загружается CSS -->
  <!-- Браузер перерендерит элементы (перерисовка) -->
</body>

FOUC (Flash of Unstyled Content) - когда содержимое сначала видно без стилей, а потом применяются стили. Это плохой UX.

4. Детальное объяснение: почему скрипты внизу

Без атрибутов (синхронные)

<!-- ПЛОХО: блокирующий скрипт в <head> -->
<head>
  <script src="/heavy-lib.js"></script> <!-- Браузер ждёт загрузки и выполнения -->
</head>
<body>
  <h1>Контент</h1> <!-- Не отображается до выполнения скрипта -->
</body>

<!-- ХОРОШО: скрипт внизу -->
<body>
  <h1>Контент</h1> <!-- Отображается сразу -->
  
  <script src="/heavy-lib.js"></script> <!-- Загружается после парсинга HTML -->
</body>

С атрибутом async

<!-- async: загружается параллельно, но выполняется сразу как готов -->
<head>
  <script async src="/script1.js"></script>
  <script async src="/script2.js"></script>
</head>
<body>
  <h1>Контент</h1> <!-- Может быть перерыв при выполнении скрипта! -->
</body>

<!-- Временная шкала: -->
<!-- |--- парсинг HTML ---| -->
<!--          |-- script1 выполняется --| -->
<!--     |-- script2 выполняется --| -->

Проблема: скрипты выполняются в случайном порядке! Если script2 зависит от script1 - будет ошибка.

С атрибутом defer

<!-- defer: загружается параллельно, выполняется после парсинга HTML -->
<head>
  <script defer src="/script1.js"></script>
  <script defer src="/script2.js"></script>
</head>
<body>
  <h1>Контент</h1> <!-- Отображается БЕЗ перерывов -->
</body>

<!-- Временная шкала: -->
<!-- |--- парсинг HTML ---| -->
<!--                      |-- script1 выполняется --| -->
<!--                                                |-- script2 выполняется --| -->

Это лучшее решение для большинства случаев!

5. Практические рекомендации

Современный подход (Next.js / React)

<!DOCTYPE html>
<html>
<head>
  <!-- Meta информация -->
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My App</title>
  
  <!-- CSS ссылки -->
  <link rel="stylesheet" href="/_next/static/css/main.css">
  
  <!-- Предзагрузка критичных ресурсов -->
  <link rel="preconnect" href="https://api.example.com">
  <link rel="dns-prefetch" href="https://cdn.example.com">
</head>
<body>
  <div id="__next"></div>
  
  <!-- Скрипты приложения внизу -->
  <script src="/_next/static/chunks/main.js"></script>
</body>
</html>

Для внешних скриптов (Google Analytics, Sentry)

<head>
  <!-- Внешние скрипты с async в <head> -- они не блокируют -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=GA_ID"></script>
  <script async src="https://cdn.sentry.io/sentry.js"></script>
</head>
<body>
  <!-- ... -->
</body>

Эти скрипты не критичны и можно загружать параллельно.

6. Сравнение разных подходов

// Временная диаграмма загрузки страницы

// ПЛОХО: синхронный скрипт в <head>
CSS:     [==================]
HTML:    [======X      ]
         HTML блокирован скриптом
Script:       [=========]
Общее время: ~3 секунды

// ЛУЧШЕ: async скрипты в <head>
CSS:     [==================]
HTML:    [====================]    Парсинг не прерывается
Script1: [=======]
Script2:     [========]
Общее время: ~2 секунды

// ЛУЧШЕ ВСЕГО: defer скрипты в <head> + CSS
CSS:     [==================]
HTML:    [====================]    Парсинг не прерывается
Script1:                  [=======]
Script2:                         [========]
Общее время: ~2.2 секунды
        Скрипты выполняются в правильном порядке

7. Специальные случаи

Inline скрипты

<!-- Inline скрипты блокируют парсинг HTML -->
<head>
  <link rel="stylesheet" href="/styles.css">
  <script>
    // Инициализация
    window.config = { /* ... */ };
  </script> <!-- Используй для критичной конфигурации только -->
</head>

Загрузка скриптов динамически

// Загрузить скрипт после загрузки страницы
function loadScript(src) {
  const script = document.createElement('script');
  script.src = src;
  script.async = true;
  document.head.appendChild(script);
}

// После того как DOM готов
window.addEventListener('DOMContentLoaded', () => {
  loadScript('/heavy-feature.js');
});

Предзагрузка vs Prefetch

<!-- preload: высокий приоритет, загруди сразу -->
<head>
  <link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
  <link rel="preload" href="/hero-image.jpg" as="image">
</head>

<!-- prefetch: низкий приоритет, загруди если будет время -->
<head>
  <link rel="prefetch" href="/about-page.html">
  <link rel="prefetch" href="/styles-about.css">
</head>

8. Core Web Vitals и производительность

<!-- Оптимизировано для Core Web Vitals -->
<head>
  <!-- 1. LCP (Largest Contentful Paint) -->
  <!-- Preload критичные ресурсы -->
  <link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
  <link rel="preload" href="/hero-image.jpg" as="image">
  
  <!-- 2. CLS (Cumulative Layout Shift) -->
  <!-- Сразу определи размеры -->
  <style>
    .hero { min-height: 400px; } /* Предотвращает сдвиг контента -->
  </style>
  
  <!-- 3. FID (First Input Delay) -->
  <!-- defer скрипты для неблокирующего выполнения -->
  <script defer src="/main.js"></script>
</head>
<body>
  <!-- ... -->
</body>
</html>

Чеклист оптимизации

  • CSS в <head> - всегда
  • Скрипты внизу <body> или в <head> с defer
  • Используй async только для независимых скриптов
  • Используй preload для критичных ресурсов
  • Минимизируй inline скрипты в <head>
  • Избегай FOUC (Flash of Unstyled Content)
  • Проверяй загрузку с помощью DevTools Performance

Заключение

Порядок и размещение <link> и <script> критичны для:

  • Производительности - правильный порядок ускоряет загрузку
  • UX - избегаем вспышек неинтегрированного контента
  • Функциональности - скрипты выполняются в правильном порядке
  • SEO - быстрая загрузка улучшает рейтинг

Практическое правило: CSS в head, скрипты в конце body (или с defer в head).

Есть ли разница в каком порядке указывать теги link и script? | PrepBro