Загрузка страниц и ресурсов

05-01-26 13:23:56


Image for the Загрузка страниц и ресурсов

Как браузер загружает страницу: базовая картина

Когда пользователь открывает страницу, браузер выполняет несколько этапов:

  • Загружает HTML
  • Парсит HTML и строит DOM
  • Загружает внешние ресурсы (CSS, JS, изображения, шрифты)
  • Исполняет JavaScript
  • Рисует страницу (render)
  • Сообщает о готовности через события (events)

Важно: эти процессы частично параллельны, но JavaScript способен блокировать парсер — отсюда все тонкости.

События жизненного цикла страницы

DOMContentLoaded

​Событие срабатывает, когда:

  • HTML полностью загружен
  • DOM полностью построен. Но изображения, шрифты и другие ресурсы могут ещё загружаться.

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

  • Инициализация UI
  • Навешивание обработчиков
  • Работа с DOM-элементами
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM готов');
});

Это самое популярное и безопасное событие для старта логики интерфейса.

load

​Срабатывает, когда:

  • DOM готов
  • Все ресурсы страницы полностью загружены (images, css, iframe и т.д.)
window.addEventListener('load', () => {
console.log('Страница и все ресурсы загружены');
});

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

  • Работа с размерами изображений
  • Ленивая инициализация тяжёлых виджетов
  • Метрики реального рендера

beforeunload

​Срабатывает перед тем, как пользователь покинет страницу.

Типичные кейсы

  • Предупреждение о несохранённых данных
  • Завершение пользовательской сессии

unload

Срабатывает в момент выгрузки страницы.

window.addEventListener('unload', () => {
console.log('Страница выгружается');
});

Ограничения:

  • Асинхронные операции (fetch, setTimeout) не гарантированы
  • Не использовать для аналитики

Скрипты: async и defer

Обычный <script>

<script src="app.js"></script>
  • HTML-парсер останавливается
  • Скрипт загружается и сразу выполняется
  • Блокирует рендер

​​defer

​<script src="app.js" defer></script>
  • Загружается параллельно HTML
  • Выполняется после построения DOM
  • Порядок скриптов сохраняется
  • DOMContentLoaded ждёт выполнения defer-скриптов

​​Лучший выбор для большинства приложений

async

​<script src="analytics.js" async></script>
  • Загружается параллельно
  • Выполняется сразу после загрузки
  • Порядок выполнения не гарантирован
  • Не блокирует HTML

​Используется для

  • Аналитики
  • Рекламы
  • Независимых скриптов

Загрузка ресурсов: onload и onerror

onload

​Срабатывает, когда конкретный ресурс успешно загружен.

const img = new Image();
img.src = '/photo.jpg';

img.onload = () => {
console.log('Изображение загружено');
};

Работает для:

  • <img>
  • <script>
  • <link>
  • <iframe>

onerror

​Срабатывает при ошибке загрузки.

img.onerror = () => {
console.log('Ошибка загрузки изображения');
};

Типичные сценарии

  • Фолбэк-изображения
  • Повторная загрузка
  • Логирование ошибок CDN

Как всё это связано между собой

Последовательность в реальной жизни выглядит примерно так:

  1. HTML начинает парситься
  2. defer и async скрипты загружаются
  3. DOM построен → DOMContentLoaded
  4. defer-скрипты выполнены
  5. Загружены все ресурсы → load
  6. Пользователь закрывает вкладку → beforeunloadunload