Подія unload
unload, це подія, яка виникає тоді, коли документ вивантажується з пам'яті браузера. Вона спрацьовує в самий останній момент життя сторінки, коли зупинити перехід уже не можна, а можна лише швидко прибрати за собою.
Теорія
TL;DR
unloadвиникає, коли користувач закриває вкладку, оновлює сторінку (F5), переходить за посиланням або на іншу сторінку з повним перезавантаженням.- Зупинити перехід або показати діалог з обробника
unloadнеможливо, для цього існуєbeforeunload. - Асинхронні операції (
fetch,setTimeout) не встигають виконатися: браузер їх не чекає. - Працюють лише синхронні дії, наприклад запис у
localStorage, плюсnavigator.sendBeacon(). - У частині браузерів (Safari, iOS)
unloadможе взагалі не викликатися; сучасна заміна, цеpagehide. - Типові задачі: логування виходу, збереження стану, закриття WebSocket-з'єднань.
Швидкий приклад
window.addEventListener('unload', () => {
// спрацює в самий останній момент, коли сторінка вже йде з пам'яті
console.log('Сторінка вивантажується...');
});Коли спрацьовує unload
Подія виникає, коли документ виходить з пам'яті браузера. На практиці це означає, що користувач:
- закриває вкладку;
- оновлює сторінку (
F5); - переходить за іншим посиланням;
- або переходить на іншу сторінку в SPA при повному перезавантаженні.
Типові сценарії застосування:
- надсилання статистики або логів «перед виходом» користувача;
- збереження даних у
localStorage/sessionStorage; - закриття з'єднань, WebSocket, звільнення ресурсів.
Наприклад, зберегти час останнього візиту:
window.addEventListener('unload', () => {
localStorage.setItem('lastVisited', new Date().toISOString());
});unload це не beforeunload
Дві події легко переплутати, але вони вирішують різні задачі: beforeunload спрацьовує перед вивантаженням і ще може його зупинити, unload спрацьовує під час вивантаження, коли вже пізно щось вирішувати.
| Властивість | beforeunload | unload |
|---|---|---|
| Коли спрацьовує | Перед вивантаженням | Під час вивантаження |
| Чи можна зупинити вихід | Так (preventDefault()) | Ні |
| Чи можна показати попередження | Так | Ні |
| Чи можна виконувати код | Так, але обмежено | Дуже обмежено |
| Типові задачі | Попередити про незбережені дані | Очищення, логування |
Обмеження і нюанси
Сучасні браузери сильно обмежують unload, щоб не гальмувати закриття сторінок:
- Асинхронні дії (
fetch,setTimeout) не працюють, браузер не чекає їхнього завершення. - Не можна показати діалог або модальне вікно.
- Працюють тільки синхронні операції, наприклад запис у
localStorage, абоnavigator.sendBeacon(). - У деяких браузерах (Safari, iOS)
unloadвзагалі не викликається, там використовуютьpagehide.
Додатковий мінус: сама наявність обробника unload (як і beforeunload) робить сторінку непридатною для bfcache, кеша «назад/вперед», тому повернення на неї стає повільнішим.
Рекомендована альтернатива: pagehide
pagehide, це сучасніша і надійніша подія, особливо в мобільних браузерах:
window.addEventListener('pagehide', (event) => {
// event.persisted === true означає, що сторінка йде в bfcache
console.log('Сторінка прихована або вивантажена');
});Вона працює навіть при переході на іншу вкладку і спрацьовує надійніше, ніж unload. Для аналітики часто беруть ще й visibilitychange зі станом hidden, бо на мобільних це єдиний момент, який гарантовано настане.
Надсилання аналітики при закритті сторінки
Єдиний безпечний спосіб відправити дані на сервер у момент закриття, це navigator.sendBeacon(): запит ставиться в чергу браузера і буде доставлений навіть після того, як сторінка зникне.
window.addEventListener('unload', () => {
navigator.sendBeacon('/analytics', JSON.stringify({ event: 'exit' }));
});Формально виклик асинхронний, але браузер бере доставку на себе, тому дані не губляться, як це сталося б зі звичайним fetch.
Підсумок по події:
| Що робить | Подія unload |
|---|---|
| Коли спрацьовує | Коли користувач залишає сторінку |
| Чи можна зупинити перехід | Ні |
| Для чого підходить | Очищення, логи, збереження стану |
| Чи працює асинхронно | Ні (тільки синхронно або через sendBeacon) |
| Сучасна альтернатива | pagehide |
| Часте застосування | Аналітика, збереження стану |
Запам'ятай просто:
beforeunload, це «попередити перед виходом»,unload, це «прибрати за собою після виходу».
Типові помилки
- Робити
fetchуunload. Браузер обриває запит разом зі сторінкою; потрібенnavigator.sendBeacon(). - Розраховувати на
setTimeoutабо проміси. Мікро- і макрозадачі вже не виконаються, документ іде з пам'яті. - Намагатися скасувати перехід у
unload.preventDefault()тут не має ефекту, це задачаbeforeunload. - Покладатися на
unloadв мобільному Safari. Подія може не викликатися взагалі, стан буде втрачено; слухайтеpagehideабоvisibilitychange. - Забувати, що обробник ламає bfcache. Сторінка перестає кешуватися, і повернення «назад» відпрацьовує повільніше.
- Складна робота в обробнику. Довгий синхронний код відчутно затримує закриття вкладки для користувача.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.