API жизненного цикла страницы

Browser Support

  • Хром: 68.
  • Край: 79.
  • Firefox: не поддерживается.
  • Safari: не поддерживается.

Современные браузеры иногда приостанавливают загрузку страниц или полностью удаляют их при ограничении системных ресурсов. В будущем браузеры захотят делать это проактивно, чтобы потреблять меньше энергии и памяти. API жизненного цикла страниц предоставляет хуки жизненного цикла, чтобы ваши страницы могли безопасно обрабатывать эти действия браузера, не влияя на пользовательский опыт. Ознакомьтесь с API, чтобы решить, стоит ли реализовывать эти функции в вашем приложении.

Фон

Жизненный цикл приложения — ключевой способ управления ресурсами в современных операционных системах. В Android, iOS и последних версиях Windows приложения могут запускаться и останавливаться операционной системой в любое время. Это позволяет этим платформам оптимизировать и перераспределять ресурсы в соответствии с потребностями пользователя.

В вебе исторически не существовало такого жизненного цикла, и приложения могли поддерживаться в рабочем состоянии неограниченное время. При большом количестве запущенных веб-страниц критически важные системные ресурсы, такие как память, процессор, аккумулятор и сеть, могут быть перегружены, что приводит к ухудшению пользовательского опыта.

Хотя веб-платформа уже давно поддерживает события, связанные с состояниями жизненного цикла, такие как load , unload и visibilitychange , эти события позволяют разработчикам реагировать только на изменения состояний жизненного цикла, инициированные пользователем. Для надёжной работы веб-приложений на маломощных устройствах (и в целом для повышения ресурсоёмкости на всех платформах) браузерам необходим способ проактивного освобождения и перераспределения системных ресурсов.

На самом деле, современные браузеры уже предпринимают активные меры по экономии ресурсов для страниц в фоновых вкладках, и многие браузеры (особенно Chrome) хотели бы делать это гораздо чаще, чтобы уменьшить общее потребление ресурсов.

Проблема в том, что разработчики не могут подготовиться к подобным системным вмешательствам или даже знать об их возникновении. Это означает, что браузерам приходится быть осторожными, иначе они рискуют нарушить работу веб-страниц.

API жизненного цикла страницы пытается решить эту проблему следующим образом:

  • Внедрение и стандартизация концепции состояний жизненного цикла в Интернете.
  • Определение новых, инициируемых системой состояний, позволяющих браузерам ограничивать ресурсы, которые могут потребляться скрытыми или неактивными вкладками.
  • Создание новых API и событий, которые позволяют веб-разработчикам реагировать на переходы в эти новые состояния и из них, инициированные системой.

Это решение обеспечивает предсказуемость, необходимую веб-разработчикам для создания приложений, устойчивых к вмешательству системы, и позволяет браузерам более агрессивно оптимизировать системные ресурсы, что в конечном итоге приносит пользу всем веб-пользователям.

В оставшейся части этой публикации будут представлены новые функции жизненного цикла страницы и рассмотрено их взаимодействие со всеми существующими состояниями и событиями веб-платформы. Также будут даны рекомендации и рекомендации по видам работ, которые разработчикам следует (и не следует) выполнять в каждом состоянии.

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

Все состояния жизненного цикла страницы дискретны и взаимоисключающи, то есть страница может находиться только в одном состоянии одновременно. Большинство изменений состояния жизненного цикла страницы, как правило, отслеживаются через события DOM (исключения см. в рекомендациях разработчиков для каждого состояния ).

Возможно, самый простой способ объяснить состояния жизненного цикла страницы, а также события, сигнализирующие о переходах между ними, — это воспользоваться диаграммой:

Визуальное представление состояния и потока событий, описанных в этом документе.
Состояние API жизненного цикла страницы и поток событий.

Штаты

В следующей таблице подробно описывается каждое состояние. В ней также перечислены возможные состояния, которые могут возникнуть до и после текущего состояния, а также события, которые разработчики могут использовать для отслеживания изменений.

Состояние Описание
Активный

Страница находится в активном состоянии, если она видима и имеет фокус ввода.

Возможные предыдущие состояния:
пассивный (через событие focus )
заморожено (через событие resume , затем событие pageshow )

Возможные следующие состояния:
пассивный (через событие blur )

Пассивный

Страница находится в пассивном состоянии, если она видима и не имеет фокуса ввода.

Возможные предыдущие состояния:
активный (через событие blur )
скрытый (через событие visibilitychange )
заморожено (через событие resume , затем событие pageshow )

Возможные следующие состояния:
активный (через событие focus )
скрытый (через событие visibilitychange )

Скрытый

Страница находится в скрытом состоянии, если она не видна (и не была заморожена, удалена или прекращена).

Возможные предыдущие состояния:
пассивный (через событие visibilitychange )
заморожено (через событие resume , затем событие pageshow )

Возможные следующие состояния:
пассивный (через событие visibilitychange )
заморожено (через событие freeze )
отменено (события не были запущены)
завершено (события не запущены)

Замороженный

В замороженном состоянии браузер приостанавливает выполнение замораживаемых задач в очередях задач страницы до тех пор, пока страница не будет разморожена. Это означает, что такие функции, как таймеры JavaScript и обратные вызовы выборки, не запускаются. Уже запущенные задачи могут быть завершены (в первую очередь, обратный вызов freeze ), но их возможности и продолжительность выполнения могут быть ограничены.

Браузеры замораживают страницы, чтобы сэкономить ресурсы процессора, аккумулятора и трафика; они также делают это для ускорения навигации вперед/назад , избегая необходимости полной перезагрузки страницы.

Возможные предыдущие состояния:
скрыто (через событие freeze )

Возможные следующие состояния:
активный (через событие resume , затем событие pageshow )
пассивный (через событие resume , затем событие pageshow )
скрыто (через событие resume )
отменено (события не были запущены)

Прекращено

Страница находится в состоянии завершения, как только браузер начал её выгрузку и очистку из памяти. В этом состоянии запуск новых задач невозможен, а выполняемые задачи могут быть завершены, если выполняются слишком долго.

Возможные предыдущие состояния:
скрытый (через событие pagehide )

Возможные следующие состояния:
НИКТО

Выброшено

Страница находится в состоянии «сброшена» , когда она выгружается браузером в целях экономии ресурсов. В этом состоянии не могут выполняться никакие задачи, обратные вызовы событий или JavaScript-код любого типа, поскольку сброс обычно происходит в условиях ограниченности ресурсов, когда запуск новых процессов невозможен.

В сброшенном состоянии сама вкладка (включая заголовок вкладки и значок) обычно видна пользователю, даже если страница удалена.

Возможные предыдущие состояния:
скрыто (события не запущены)
заморожено (события не запущены)

Возможные следующие состояния:
НИКТО

События

Браузеры генерируют множество событий, но лишь небольшая их часть сигнализирует о возможном изменении состояния жизненного цикла страницы. В следующей таблице перечислены все события, относящиеся к жизненному циклу, и состояния, в которые они могут переходить и из которых могут переходить.

Имя Подробности
focus

Элемент DOM получил фокус.

Примечание: событие focus не обязательно сигнализирует об изменении состояния. Оно сигнализирует об изменении состояния только в том случае, если страница ранее не имела фокуса ввода.

Возможные предыдущие состояния:
пассивный

Возможные текущие состояния:
активный

blur

Элемент DOM потерял фокус.

Примечание: событие blur не обязательно сигнализирует об изменении состояния. Оно сигнализирует об изменении состояния только в том случае, если страница больше не находится в фокусе ввода (т.е. страница не просто переключила фокус с одного элемента на другой).

Возможные предыдущие состояния:
активный

Возможные текущие состояния:
пассивный

visibilitychange

Значение visibilityState документа изменилось. Это может произойти, когда пользователь переходит на новую страницу, переключает вкладки, закрывает вкладку, сворачивает или закрывает браузер, а также переключает приложения в мобильных операционных системах.

Возможные предыдущие состояния:
пассивный
скрытый

Возможные текущие состояния:
пассивный
скрытый

freeze *

Страница только что заморожена. Ни одна из замороженных задач в очередях задач страницы не будет запущена.

Возможные предыдущие состояния:
скрытый

Возможные текущие состояния:
замороженный

resume *

Браузер возобновил замороженную страницу.

Возможные предыдущие состояния:
замороженный

Возможные текущие состояния:
активный (если за ним следует событие pageshow )
пассивный (если за ним следует событие pageshow )
скрытый

pageshow

Выполняется переход к записи истории сеанса.

Это может быть либо загрузка новой страницы, либо страница, взятая из кэша возврата/передачи . Если страница была взята из кэша возврата/передачи, свойство persisted события равно true , в противном случае — false .

Возможные предыдущие состояния:
заморожен (также сработало бы событие resume )

Возможные текущие состояния:
активный
пассивный
скрытый

pagehide

Просматривается запись истории сеанса.

Если пользователь переходит на другую страницу и браузер может добавить текущую страницу в кэш возврата/передачи для повторного использования в будущем, свойство persisted события равно true . Если true , страница переходит в состояние заморозки , в противном случае — в состояние завершения .

Возможные предыдущие состояния:
скрытый

Возможные текущие состояния:
заморожено ( event.persisted равно true, следует событие freeze )
завершено ( event.persisted равно false, следует событие unload )

beforeunload

Окно, документ и его ресурсы будут выгружены. Документ всё ещё виден, и событие всё ещё можно отменить.

Важно: событие beforeunload следует использовать только для оповещения пользователя о несохранённых изменениях. После сохранения изменений событие следует удалить. Его ни в коем случае не следует добавлять на страницу без каких-либо условий, так как в некоторых случаях это может снизить производительность. Подробнее см. в разделе «Устаревшие API» .

Возможные предыдущие состояния:
скрытый

Возможные текущие состояния:
прекращено

unload

Страница выгружается.

Внимание: использование события unload никогда не рекомендуется, поскольку оно ненадёжно и в некоторых случаях может снизить производительность. Подробнее см. в разделе «Устаревшие API» .

Возможные предыдущие состояния:
скрытый

Возможные текущие состояния:
прекращено

* Указывает на новое событие, определенное API жизненного цикла страницы.

Новые функции, добавленные в Chrome 68

На предыдущей диаграмме показаны два состояния, инициированные системой, а не пользователем: заморожено и сброшено . Как упоминалось ранее, современные браузеры уже иногда замораживают и сбрасывают скрытые вкладки (по своему усмотрению), но разработчики не могут знать, когда это происходит.

В Chrome 68 разработчики теперь могут наблюдать, когда скрытая вкладка замораживается и размораживается, прослушивая события freeze и resume в document .

document.addEventListener('freeze', (event) => {
  // The page is now frozen.
});

document.addEventListener('resume', (event) => {
  // The page has been unfrozen.
});

Начиная с Chrome 68, объект document в десктопной версии Chrome включает свойство wasDiscarded ( поддержка Android отслеживается в этой проблеме ). Чтобы определить, была ли страница удалена в скрытой вкладке, можно проверить значение этого свойства во время загрузки страницы (примечание: для повторного использования удаленных страниц необходимо перезагрузить их).

if (document.wasDiscarded) {
  // Page was previously discarded by the browser while in a hidden tab.
}

Советы о том, что важно делать в случаях freeze и resume , а также о том, как обрабатывать и готовиться к удалению страниц, см. в рекомендациях разработчиков для каждого состояния .

В следующих нескольких разделах представлен обзор того, как эти новые функции вписываются в существующие состояния и события веб-платформы.

Как наблюдать за состояниями жизненного цикла страницы в коде

В активном , пассивном и скрытом состояниях можно запустить код JavaScript, который определяет текущее состояние жизненного цикла страницы из существующих API веб-платформы.

const getState = () => {
  if (document.visibilityState === 'hidden') {
    return 'hidden';
  }
  if (document.hasFocus()) {
    return 'active';
  }
  return 'passive';
};

С другой стороны, состояния заморозки и завершения могут быть обнаружены только в соответствующем прослушивателе событий ( freeze и pagehide ) по мере изменения состояния.

Как наблюдать за изменениями состояния

Используя функцию getState() определенную ранее, вы можете наблюдать все изменения состояния жизненного цикла страницы с помощью следующего кода.

// Stores the initial state using the `getState()` function (defined above).
let state = getState();

// Accepts a next state and, if there's been a state change, logs the
// change to the console. It also updates the `state` value defined above.
const logStateChange = (nextState) => {
  const prevState = state;
  if (nextState !== prevState) {
    console.log(`State change: ${prevState} >>> ${nextState}`);
    state = nextState;
  }
};

// Options used for all event listeners.
const opts = {capture: true};

// These lifecycle events can all use the same listener to observe state
// changes (they call the `getState()` function to determine the next state).
['pageshow', 'focus', 'blur', 'visibilitychange', 'resume'].forEach((type) => {
  window.addEventListener(type, () => logStateChange(getState()), opts);
});

// The next two listeners, on the other hand, can determine the next
// state from the event itself.
window.addEventListener('freeze', () => {
  // In the freeze event, the next state is always frozen.
  logStateChange('frozen');
}, opts);

window.addEventListener('pagehide', (event) => {
  // If the event's persisted property is `true` the page is about
  // to enter the back/forward cache, which is also in the frozen state.
  // If the event's persisted property is not `true` the page is
  // about to be unloaded.
  logStateChange(event.persisted ? 'frozen' : 'terminated');
}, opts);

Этот код делает три вещи:

  • Устанавливает начальное состояние с помощью функции getState() .
  • Определяет функцию, которая принимает следующее состояние и, если есть изменение, регистрирует изменения состояния в консоли.
  • Добавляет прослушиватели событий для всех необходимых событий жизненного цикла, которые, в свою очередь, вызывают logStateChange() , передавая следующее состояние.

Обратите внимание на то, что в этом коде все прослушиватели событий добавляются в window и все они передают {capture: true} . Этому есть несколько причин:

  • Не все события жизненного цикла страницы имеют одинаковую цель. pagehide и pageshow запускаются для window ; visibilitychange , freeze и resume запускаются для document , а focus и blur запускаются для соответствующих им элементов DOM.
  • Большинство этих событий не всплывают, что означает невозможность добавления прослушивателей событий без захвата к общему родительскому элементу и наблюдения за ними всеми.
  • Фаза захвата выполняется до целевой фазы или фазы пузырька, поэтому добавление прослушивателей туда помогает гарантировать, что они будут выполнены до того, как другой код сможет их отменить.

Рекомендации разработчиков для каждого штата

Как разработчикам, вам важно понимать состояния жизненного цикла страницы и уметь наблюдать за ними в коде, поскольку тип работы, которую вам следует (и не следует) выполнять, во многом зависит от того, в каком состоянии находится ваша страница.

Например, совершенно бессмысленно показывать пользователю временное уведомление, если страница скрыта. Хотя этот пример довольно очевиден, есть и другие, менее очевидные рекомендации, которые стоит перечислить.

Состояние Рекомендации разработчиков
Active

Активное состояние — это самое критическое время для пользователя, а значит, самое важное время для того, чтобы ваша страница реагировала на действия пользователя .

Любая работа, не связанная с пользовательским интерфейсом, которая может блокировать основной поток, должна быть переведена в режим простоя или перенесена на веб-процесс .

Passive

В пассивном состоянии пользователь не взаимодействует со страницей, но всё ещё видит её. Это означает, что обновления пользовательского интерфейса и анимация по-прежнему должны быть плавными, но время этих обновлений менее критично.

Когда страница переходит из активного состояния в пассивное , самое время сохранить несохраненное состояние приложения.

Hidden

Когда страница переходит из пассивного состояния в скрытое , возможно, пользователь не будет с ней взаимодействовать до тех пор, пока она не будет перезагружена.

Переход в скрытое состояние также часто является последним изменением состояния, которое надежно отслеживается разработчиками (это особенно актуально для мобильных устройств, поскольку пользователи могут закрывать вкладки или само приложение браузера, а события beforeunload , pagehide и unload в этих случаях не срабатывают).

Это означает, что следует рассматривать скрытое состояние как вероятное завершение сеанса пользователя. Другими словами, необходимо сохранять любое несохранённое состояние приложения и отправлять любые неотправленные аналитические данные.

Вам также следует прекратить обновлять пользовательский интерфейс (поскольку пользователь их не увидит), а также остановить выполнение любых задач, которые пользователь не хочет выполнять в фоновом режиме.

Frozen

В замороженном состоянии замораживаемые задачи в очередях задач приостанавливаются до тех пор, пока страница не будет разморожена, что может никогда не произойти (например, если страница будет удалена).

Это означает, что когда страница переходит из состояния скрытой в состояние замороженной , крайне важно остановить все таймеры или разорвать все соединения, которые в случае заморозки могут повлиять на другие открытые вкладки в том же источнике или повлиять на способность браузера помещать страницу в возвратный кэш .

В частности, важно, чтобы вы:

  • Закройте все открытые соединения IndexedDB .
  • Закройте открытые соединения BroadcastChannel .
  • Закройте активные соединения WebRTC .
  • Остановите все сетевые опросы или закройте все открытые соединения Web Socket .
  • Снимите все удерживаемые веб-блокировки .

Вам также следует сохранять любое динамическое состояние представления (например, позицию прокрутки в бесконечном списке) в sessionStorage (или IndexedDB через commit() ), которое вы хотите восстановить, если страница будет удалена и перезагружена позже.

Если страница перейдет из состояния «заморожено» обратно в состояние «скрыто» , вы можете повторно открыть любые закрытые соединения или возобновить любой опрос, который вы остановили, когда страница была изначально заморожена.

Terminated

Обычно вам не нужно предпринимать никаких действий, когда страница переходит в состояние завершения .

Поскольку страницы, выгружаемые в результате действий пользователя, всегда проходят через скрытое состояние, прежде чем перейти в состояние завершения , именно в скрытом состоянии должна выполняться логика завершения сеанса (например, сохранение состояния приложения и предоставление отчетов в аналитику).

Кроме того (как упоминалось в рекомендациях для скрытого состояния ), разработчикам очень важно понимать, что переход в завершенное состояние во многих случаях не может быть надежно обнаружен (особенно на мобильных устройствах), поэтому разработчики, которые зависят от событий завершения (например, beforeunload , pagehide и unload ), вероятно, теряют данные.

Discarded

Разработчики не могут наблюдать за состоянием «удалённая страница» в момент удаления страницы. Это связано с тем, что страницы обычно удаляются из-за ограничений ресурсов, и разморозка страницы только для того, чтобы позволить скрипту выполниться в ответ на событие удаления, в большинстве случаев просто невозможна.

В результате вам следует подготовиться к возможности отмены при изменении со скрытого на замороженный , а затем вы сможете отреагировать на восстановление отмененной страницы во время ее загрузки, проверив document.wasDiscarded .

Опять же, поскольку надежность и порядок событий жизненного цикла не реализованы одинаково во всех браузерах, самый простой способ следовать советам в таблице — использовать PageLifecycle.js .

Устаревшие API жизненного цикла, которых следует избегать

По возможности следует избегать следующих событий.

Событие выгрузки

Многие разработчики рассматривают событие unload как гарантированный обратный вызов и используют его как сигнал окончания сеанса для сохранения состояния и отправки аналитических данных, но это крайне ненадёжно , особенно на мобильных устройствах! Событие unload не срабатывает во многих типичных ситуациях unload, включая закрытие вкладки из переключателя вкладок на мобильном устройстве или закрытие приложения браузера из переключателя приложений.

По этой причине всегда лучше полагаться на событие visibilitychange для определения момента завершения сеанса и рассматривать скрытое состояние как последнее надежное время для сохранения данных приложения и пользователя .

Более того, одно лишь наличие зарегистрированного обработчика событий unload (через onunload или addEventListener() ) может помешать браузерам помещать страницы в кэш возврата/передачи для более быстрой загрузки назад и вперед.

Во всех современных браузерах рекомендуется всегда использовать событие pagehide для обнаружения возможной выгрузки страницы (т.е. состояния завершения ), а не событие unload . Если вам требуется поддержка Internet Explorer версии 10 и ниже, следует настроить функцию обнаружения события pagehide и использовать unload только в том случае, если браузер не поддерживает pagehide :

const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';

window.addEventListener(terminationEvent, (event) => {
  // Note: if the browser is able to cache the page, `event.persisted`
  // is `true`, and the state is frozen rather than terminated.
});

Событие перед загрузкой

Событие beforeunload имеет ту же проблему, что и событие unload : исторически сложилось так, что наличие события beforeunload могло препятствовать помещению страниц в обратный кэш . В современных браузерах этого ограничения нет. Хотя некоторые браузеры в качестве меры предосторожности не вызывают событие beforeunload при попытке поместить страницу в обратный кэш, что означает, что это событие ненадёжно в качестве сигнала окончания сеанса. Кроме того, некоторые браузеры (включая Chrome ) требуют взаимодействия пользователя со страницей перед срабатыванием события beforeunload , что ещё больше снижает его надёжность.

Одно из различий между beforeunload и unload заключается в том, что beforeunload можно использовать в допустимых случаях. Например, когда вы хотите предупредить пользователя о том, что у него есть несохранённые изменения, которые будут потеряны, если он продолжит выгружать страницу.

Поскольку существуют веские причины использовать beforeunload , рекомендуется добавлять прослушиватели beforeunload только в том случае, если у пользователя есть несохраненные изменения, а затем удалять их сразу после сохранения.

Другими словами, не делайте этого (поскольку это безусловно добавляет прослушиватель beforeunload ):

addEventListener('beforeunload', (event) => {
  // A function that returns `true` if the page has unsaved changes.
  if (pageHasUnsavedChanges()) {
    event.preventDefault();

    // Legacy support for older browsers.
    event.returnValue = true;
  }
});

Вместо этого сделайте следующее (поскольку он добавляет прослушиватель beforeunload только тогда, когда он нужен, и удаляет его, когда он не нужен):

const beforeUnloadListener = (event) => {
  event.preventDefault();

  // Legacy support for older browsers.
  event.returnValue = true;
};

// A function that adds a `beforeunload` listener if there are unsaved changes.
onPageHasUnsavedChanges(() => {
  addEventListener('beforeunload', beforeUnloadListener);
});

// A function that removes the `beforeunload` listener when the page's unsaved
// changes are resolved.
onAllChangesSaved(() => {
  removeEventListener('beforeunload', beforeUnloadListener);
});

Часто задаваемые вопросы

Почему нет состояния «загрузка»?

API жизненного цикла страницы определяет состояния как дискретные и взаимоисключающие. Поскольку страница может быть загружена в активном, пассивном или скрытом состоянии, и поскольку она может менять состояния (или даже быть остановлена) до завершения загрузки, отдельное состояние загрузки не имеет смысла в рамках этой парадигмы.

Моя страница выполняет важную работу, когда она скрыта. Как сделать, чтобы ее не заморозили или не удалили?

Существует множество обоснованных причин, по которым веб-страницы не следует замораживать в скрытом режиме. Самый очевидный пример — приложение, воспроизводящее музыку.

Существуют также ситуации, когда для Chrome было бы рискованно отбрасывать страницу, например, если она содержит форму с неотправленными данными пользователя или если на ней есть обработчик beforeunload , который предупреждает о выгрузке страницы.

На данный момент Chrome будет действовать консервативно при удалении страниц и делать это только тогда, когда будет уверен, что это не повлияет на пользователей. Например, страницы, на которых в скрытом состоянии замечены какие-либо из следующих действий, не будут удалены, за исключением случаев крайней нехватки ресурсов:

  • Воспроизведение аудио
  • Использование WebRTC
  • Обновление заголовка таблицы или значка
  • Показ оповещений
  • Отправка push-уведомлений

Текущие функции списка, используемые для определения возможности безопасной заморозки или удаления вкладки, см. в статье: Эвристика заморозки и удаления в Chrome.

Что такое возвратный кэш?

Кэш «назад/вперед» — это термин, используемый для описания оптимизации навигации, реализуемой некоторыми браузерами, которая ускоряет использование кнопок «назад» и «вперед».

Когда пользователь покидает страницу, эти браузеры замораживают её версию, чтобы её можно было быстро возобновить, если пользователь вернётся с помощью кнопок «Назад» или «Вперёд». Помните, что добавление обработчика событий unload делает такую ​​оптимизацию невозможной .

По сути, эта заморозка функционально аналогична заморозке браузеров, которая позволяет экономить ресурсы ЦП/батареи; по этой причине она считается частью замороженного состояния жизненного цикла.

Если я не могу запустить асинхронные API в замороженном или остановленном состоянии, как я могу сохранить данные в IndexedDB?

В замороженном и прекращенном состояниях замораживаемые задачи в очередях задач страницы приостанавливаются, что означает невозможность надежного использования асинхронных и основанных на обратных вызовах API.

Хотя большинство API IndexedDB основаны на обратных вызовах, метод commit() интерфейса IDBTransaction позволяет инициировать процесс фиксации активной транзакции, не дожидаясь отправки событий от ожидающих запросов. Это обеспечивает надёжный способ сохранения данных в базе данных IndexedDB в прослушивателе событий freeze или visibilitychange , поскольку фиксация выполняется немедленно, а не ставится в очередь в отдельной задаче.

Тестирование вашего приложения в замороженном и отмененном состояниях

Чтобы проверить, как ваше приложение ведет себя в замороженном и отклоненном состояниях, вы можете посетить chrome://discards чтобы фактически заморозить или отменить любую из ваших открытых вкладок.

Chrome Discards UI
Chrome Discards UI

Это позволяет вам гарантировать, что ваша страница правильно обрабатывает события freeze и resume а также флаг document.wasDiscarded при перезагрузке страниц после отмены.

Краткое содержание

Разработчики, которые заботятся об экономии системных ресурсов устройств своих пользователей, должны разрабатывать свои приложения с учётом состояний жизненного цикла страниц. Крайне важно, чтобы веб-страницы не потребляли чрезмерное количество системных ресурсов в ситуациях, которых пользователь не ожидает.

Чем больше разработчиков начнут внедрять новые API жизненного цикла страниц, тем безопаснее браузерам будет замораживать и удалять неиспользуемые страницы. Это означает, что браузеры будут потреблять меньше памяти, ресурсов процессора, батареи и сети, что выгодно для пользователей.