Ответ
Разница есть, особенно при загрузке CSS и JavaScript.
CSS (<link>) лучше размещать в <head>, чтобы стили загружались до отрисовки DOM, избегая "мерцания" нестилизованного контента (FOUC).
<script> без атрибутов async/defer блокирует парсинг HTML, поэтому их лучше ставить перед закрывающим </body>. Если скрипт критичен для отображения, можно разместить в <head> с defer.
Пример:
<head>
<link rel="stylesheet" href="styles.css"> <!-- CSS в head -->
</head>
<body>
<!-- контент -->
<script src="app.js"></script> <!-- JS перед </body> -->
</body>
Исключение:
async/deferпозволяют загружать скрипты асинхронно, не блокируя рендеринг.- Модульные скрипты (
type="module") по умолчанию работают какdefer.
Ответ 18+ 🔞
А, слушай, вот это реально важный момент, который многие на раз два проёбывают! Разница-то есть, и ещё какая, блядь.
Представь себе: браузер читает твой HTML, как книжку, сверху вниз. И вот он натыкается на твой красивый <link> со стилями. Если эту хуйню запихнуть в конец, перед </body>, то что получится? А получится, что страница сначала нарисуется вся голая, как ёбнутый скелет, а потом — бац! — на неё резко натянется CSS-одеяло. Пользователь это видит как дерганое "мерцание" или, по-умному, FOUC. Выглядит это пиздец как кустарно и дешево. Поэтому CSS — всегда, блядь, в <head>, чтобы браузер сразу знал, как всё должно выглядеть, и отрендерил уже причёсанную страницу.
А вот с этими ёбаными скриптами — история отдельная. Если ты воткнёшь обычный <script src="app.js"> в <head>, то браузер упрётся, как говно в стенку. Он остановит всё: чтение HTML, отрисовку, всё нахуй! — и будет ждать, пока этот скрипт скачается и выполнится. Пользователь в это время пялится в белый экран. Ну и нахуя так делать?
Поэтому классика жанра — скрипты кидать прямо перед </body>. К этому моменту весь DOM уже готов, можно его спокойно обвешивать обработчиками событий и не тормозить первоначальную отрисовку.
Но, как всегда, есть нюансы, ёпта!
async/defer— это магические пиздатые атрибуты. Суёшь их в скрипт в<head>и спишь спокойно.async: "Скачаю — сразу выполню, похуй на порядок". Хорошо для независимых скриптов вроде метрик.defer: "Скачаю по-быстрому, но выполню только когда весь HTML будет готов". Идеально для большинства случаев.
- Модули (
type="module") — они по умолчанию умные, какdefer. Так что их тоже можно в<head>пихать без зазрения совести.
Короче, паттерн де-факто такой:
<head>
<link rel="stylesheet" href="styles.css"> <!-- Стили тут, блядь! -->
<script src="analytics.js" async></script> <!-- Метрика пусть летит асинхронно -->
</head>
<body>
<!-- вся твоя прекрасная разметка -->
<script src="main.js"></script> <!-- Основную логику — в самый низ -->
</body>
Запомни эту простую хуйню, и FOUC с белыми экранами тебе не грозят. Всё гениальное — просто, как три копейки.