> Какие события жизненного цикла HTML-страницы существуют (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Домклик

Стек: JavaScript

> Пример ответа

Короткий ответ

Основные события жизненного цикла HTML-страницы: DOMContentLoaded, load, beforeunload, unload, pageshow и pagehide. Также существуют события, связанные с видимостью страницы: visibilitychange, freeze и resume. Ключевое различие между DOMContentLoaded и load - момент срабатывания относительно загрузки внешних ресурсов: первое происходит после построения DOM-дерева, второе - после полной загрузки всех ресурсов (изображения, стили, скрипты).

Подробное объяснение

Жизненный цикл страницы можно разделить на три фазы: загрузка, активное использование и выгрузка.

Фаза загрузки:

  • DOMContentLoaded - срабатывает, когда HTML полностью распарсен и DOM-дерево построено. Стили, изображения и iframe могут ещё загружаться. Событие не ждёт async-скрипты, но ждёт defer-скрипты.
  • load - срабатывает после полной загрузки всех ресурсов страницы: изображений, стилей, скриптов, iframe. Это последнее событие фазы загрузки.

Фаза активного использования:

  • pageshow - срабатывает при первом отображении страницы и при каждом возврате на неё из bfcache (back-forward cache). Свойство event.persisted показывает, была ли страница восстановлена из bfcache.
  • pagehide - срабатывает при уходе со страницы, включая переход в bfcache. Также имеет event.persisted.
  • visibilitychange - срабатывает при изменении видимости страницы (переключение вкладок, сворачивание окна). document.visibilityState принимает значения visible, hidden, prerender.
  • freeze и resume - связаны с заморозкой страницы браузером для экономии ресурсов (например, при скрытии вкладки). freeze срабатывает после pagehide, resume - перед pageshow.

Фаза выгрузки:

  • beforeunload - срабатывает перед выгрузкой страницы. Используется для предупреждения пользователя о несохранённых данных. Требует event.preventDefault() и установки returnValue.
  • unload - срабатывает при фактической выгрузке. Надёжность ограничена: браузеры могут не вызвать его при закрытии вкладки или крахе.

Важный нюанс: unload и beforeunload не срабатывают при восстановлении из bfcache, поэтому для аналитики и сохранения состояния лучше использовать pagehide и visibilitychange.

На практике

Для senior-позиции важно понимать не только порядок событий, но и практические сценарии:

  1. Инициализация приложения - вешать обработчики на DOMContentLoaded, если скрипт подключён в <head>. Если скрипт подключён с defer или в конце <body>, событие уже не нужно - DOM готов.

  2. Аналитика - для отправки данных об уходе со страницы использовать pagehide вместо unload, так как unload ненадёжен при bfcache. При этом использовать navigator.sendBeacon() для гарантированной отправки.

  3. Сохранение состояния - visibilitychange с document.visibilityState === 'hidden' - лучший момент для автосохранения черновиков, так как срабатывает при переключении вкладок.

  4. Предупреждение о несохранённых данных - beforeunload срабатывает только при реальном уходе, но не при переключении вкладок. Для полного покрытия комбинировать с visibilitychange.

  5. Восстановление из bfcache - если страница использует pageshow с event.persisted === true, нужно переинициализировать состояние, так как скрипты не перезапускаются, но DOM может быть изменён.

Пример кода

JAVASCRIPT
// Инициализация приложения
document.addEventListener('DOMContentLoaded', () => {
initApp();
});
window.addEventListener('load', () => {
// Тяжёлая инициализация: графики, карты, аналитика
initHeavyWidgets();
});
// Отправка аналитики при уходе
window.addEventListener('pagehide', (event) => {
if (event.persisted) {
// Страница уходит в bfcache - данные сохранятся
return;
}
navigator.sendBeacon('/api/analytics', JSON.stringify({
duration: performance.now()
}));
});
// Автосохранение при скрытии вкладки
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
saveDraft();
}
});
// Восстановление из bfcache
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
refreshState();
}
});
// Предупреждение о несохранённых данных
window.addEventListener('beforeunload', (event) => {
if (hasUnsavedChanges()) {
event.preventDefault();
event.returnValue = '';
}
});

Как отвечать на собеседовании

Начните с перечисления основных событий в хронологическом порядке. Затем выделите ключевые различия: DOMContentLoaded vs load, pagehide vs unload. Покажите понимание bfcache - это сильный сигнал для senior. Обязательно упомяните visibilitychange как современную альтернативу для многих сценариев. Приведите пример из реальной практики: почему unload ненадёжен и как вы решали эту проблему. Если спросят про порядок - расскажите полную последовательность для типичной загрузки: DOMContentLoadedload → (активное использование) → pagehidefreeze → (восстановление) → resumepageshow.

Что проверяет интервьюер

Интервьюер оценивает:

  • понимание разницы между событиями загрузки и выгрузки;
  • знание bfcache и его влияния на жизненный цикл;
  • умение выбирать правильное событие для конкретной задачи;
  • осведомлённость о современных API (sendBeacon, visibilitychange);
  • способность объяснить edge cases: что происходит при закрытии вкладки, переключении, восстановлении из кэша.

Типичные ошибки

  • Путаница между DOMContentLoaded и load - утверждение, что load срабатывает после всех скриптов, но это верно лишь частично: load ждёт все ресурсы, включая изображения.
  • Использование unload для аналитики - ненадёжно из-за bfcache и ограничений браузера.
  • Игнорирование pageshow с event.persisted - при восстановлении из bfcache скрипты не перезапускаются, но состояние может быть устаревшим.
  • Утверждение, что beforeunload срабатывает при переключении вкладок - это не так, для этого нужен visibilitychange.
  • Забывают про freeze и resume - эти события важны для мобильных браузеров и экономии ресурсов.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью