ページ ライフサイクル API

対応ブラウザ

  • Chrome: 68。
  • Edge: 79.
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

最新のブラウザでは、システム リソースが制限されている場合、ページが一時停止されたり、完全に破棄されたりすることがあります。将来的には、ブラウザでこれを積極的に行い、電力とメモリの消費量を抑えることが望まれます。Page Lifecycle API はライフサイクル フックを提供するため、ページはユーザー エクスペリエンスに影響を与えることなく、これらのブラウザの介入を安全に処理できます。API を確認して、これらの機能をアプリに実装する必要があるかどうかを判断します。

背景

アプリケーションのライフサイクルは、最新のオペレーティング システムがリソースを管理する重要な手段になります。Android、iOS、最近の Windows バージョンでは、OS によってアプリをいつでも起動および終了できます。これにより、これらのプラットフォームでリソースを最適化して、ユーザーにとって最もメリットがある場所に再割り当てすることが可能になります。

ウェブにはこれまでそのようなライフサイクルがなく、アプリは無期限に存続できます。多数のウェブページが実行されている場合、メモリ、CPU、バッテリー、ネットワークなどの重要なシステム リソースがオーバーサブスクライブされ、エンドユーザー エクスペリエンスの低下につながる可能性があります。

ウェブ プラットフォームには以前から、loadunloadvisibilitychange など、ライフサイクルの状態に関連するイベントがありましたが、これらのイベントでは、デベロッパーが開始したライフサイクル状態の変化にのみ対応できます。低電力のデバイスでウェブが確実に機能し(すべてのプラットフォームでリソースをより意識した動作を実現するため)、ブラウザはシステム リソースを事前に再利用して再割り当てする方法が必要です。

実際、現在のブラウザでは、バックグラウンド タブに表示されるページのリソースを節約するための積極的な対策を講じています。また、多くのブラウザ(特に Chrome)は、全体的なリソースのフットプリントを削減するために、その取り組みをさらに進めたいと考えています。

問題は、デベロッパーがこの種のシステム開始型介入に備える方法がなく、それが起こっていることを認識することすら持てないことです。つまり、ブラウザは保守的である必要があり、そうでないとウェブページが破損するリスクがあります。

Page Lifecycle API では、次の方法でこの問題を解決しようとします。

  • ウェブでのライフサイクルの状態のコンセプトを導入し、標準化しています。
  • システムによって開始される新しい状態を定義し、ブラウザが非表示または非アクティブなタブで消費できるリソースを制限できるようにします。
  • ウェブ デベロッパーが、これらの新しいシステム開始状態との間の遷移に応答できるようにする新しい API とイベントを作成します。

このソリューションは、システム介入に耐性のあるアプリケーションを構築するために必要な予測可能性をウェブ デベロッパーに提供します。また、ブラウザがシステム リソースをより積極的に最適化し、最終的にはすべてのウェブユーザーに利益をもたらします。

以降では、新しいページ ライフサイクル機能を紹介し、既存のすべてのウェブ プラットフォームの状態とイベントとの関係について説明します。また、各州でデベロッパーが行うべき(およびすべきでない)作業の種類に関する推奨事項とベスト プラクティスも提供します。

ページのライフサイクルの状態とイベントの概要

ページ ライフサイクルのすべての状態は互いに独立しており、相互に排他的です。つまり、ページは一度に 1 つの状態のみになります。ページのライフサイクル ステータスのほとんどの変更は、通常、DOM イベントで検出できます(例外については、各ステータスに関するデベロッパー向けの推奨事項をご覧ください)。

ページのライフサイクルの状態と、それらの状態間の遷移を示すイベントを説明する最も簡単な方法は、図を使用することです。

このドキュメントで説明する状態とイベントフローを視覚的に示したものです。
Page Lifecycle API の状態とイベントフロー。

次の表に、各状態の詳細を示します。また、前後に発生する可能性のある状態と、開発者が変更を検出するために使用できるイベントも一覧表示されます。

説明
有効

ページが可視で、入力フォーカスがある場合は、ページはアクティブ状態です。

考えられる以前の状態:
パッシブ focus イベントを介して)
フリーズ resume イベント、pageshow イベントを介して)

次の状態の候補:
パッシブ blur イベント経由)

受動

ページが可視状態で、入力フォーカスが設定されていない場合、そのページは非アクティブ状態です。

以前の状態:
アクティブ blur イベント経由)
非表示 visibilitychange イベント経由)
フリーズ resume イベント、pageshow イベント経由)

次の状態の候補:
アクティブ focus イベント経由)
非表示 visibilitychange イベント経由)

非表示

ページが非表示(フリーズ、破棄、終了されていない)場合は、非表示状態です。

考えられる以前の状態:
パッシブ visibilitychange イベント経由)
フリーズ resume イベント、次に pageshow イベント経由)

次の状態の候補:
passive visibilitychange イベント経由)
frozen freeze イベント経由)
discarded (イベントがトリガーされない)
terminated (イベントがトリガーされない)

フリーズ

フリーズ状態の場合、ページがフリーズ解除されるまで、ブラウザはページのタスクキュー内のフリーズ可能タスクの実行を停止します。つまり、JavaScript タイマーやフェッチ コールバックは実行されません。すでに実行中のタスクは終了できます(特に freeze コールバック)。ただし、実行できる処理や実行時間に制限が設けられる場合があります。

ブラウザは、CPU / バッテリー / データ使用量を節約するためにページをフリーズします。また、前後ナビゲーションを高速化するためにページ全体の再読み込みを回避するためにも、ページをフリーズします。

以前の状態:
非表示 freeze イベント経由)

次のステータス:
active resume イベント、次に pageshow イベント経由)
パッシブ resume イベント経由、次に pageshow イベント、pageshow イベント
非表示 (非表示) resume イベント経由))
非表示

終了

ページがブラウザによってアンロードされ、メモリから消去され始めると、ページは終了状態になります。この状態で 新しいタスクを開始することはできません。また、進行中のタスクが長時間実行されると、強制終了される可能性があります。

考えられる以前の状態:
非表示 pagehide イベント経由)

次の状態の候補:
なし

破棄済み

ページがリソースを節約するためにブラウザによってアンロードされると、そのページは破棄された状態になります。破棄は通常、新しいプロセスを開始できないリソース制約下で発生するため、この状態ではタスク、イベント コールバック、または任意の JavaScript を実行できません。

破棄済みの状態の場合、通常、ページは消去されていても、タブ自体(タブのタイトルやファビコンを含む)はユーザーに表示されます。

以前の状態:
非表示 (イベントは発生しない)
フリーズ (イベントは発生しない)

次の状態の候補:
なし

イベント

ブラウザは多くのイベントを送信しますが、ページ ライフサイクルの状態が変化する可能性を示すのはごく一部です。次の表に、ライフサイクルに関連するすべてのイベントの概要と、イベントの遷移元と遷移先の状態を示します。

名前 詳細
focus

DOM 要素がフォーカスを受け取りました。

注: focus イベントは、必ずしも状態の変化を通知するものではありません。ページに入力フォーカスがなかった場合にのみ、状態変化が通知されます。

以前の状態の例:
パッシブ

現在の状態の可能性:
有効

blur

DOM 要素のフォーカスが失われた。

注: blur イベントは、必ずしも状態変化を通知するわけではありません。ページに入力フォーカスがなくなった場合にのみ、状態の変化を通知します(つまり、ページが要素間でフォーカスを切り替えただけではありません)。

以前の状態:
有効

考えられる現在の状態:
パッシブ

visibilitychange

ドキュメントの visibilityState 値が変更されました。これは、ユーザーが新しいページに移動する、タブを切り替える、タブを閉じた、ブラウザを最小化または閉じた、モバイル オペレーティング システムでアプリを切り替えたときに発生します。

以前の状態の例:
パッシブ
非表示

考えられる現在の状態:
パッシブ
非表示

freeze *

ページが凍結されました。ページのタスクキュー内のフリーズ可能なタスクは開始されません。

考えられる以前の状態:
hidden

考えられる現在の状態:
フリーズ

resume *

ブラウザがフリーズしたページを再開しました。

考えられる以前の状態:
フリーズ

現在の状態の例:
アクティブ pageshow イベントの後に続く場合)
パッシブ pageshow イベントの後に続く場合)
非表示

pageshow

セッション履歴エントリがトラバース中です。

これは、まったく新しいページの読み込みであったり、バックフォワード キャッシュから取得したページであったりします。ページがバックフォワード キャッシュから取得された場合、イベントの persisted プロパティは true になり、それ以外の場合は false になります。

考えられる以前の状態:
凍結 resume イベントも発生している)

現在の状態の可能性:
アクティブ
パッシブ
非表示

pagehide

セッション履歴エントリの参照元。

ユーザーが別のページに移動し、ブラウザが現在のページをバック/フォワード キャッシュに追加して後で再利用できる場合は、イベントの persisted プロパティは true です。true の場合、ページは「フリーズ」状態になり、それ以外の場合は「終了」状態になります。

考えられる以前の状態:
hidden

現在の状態の可能性:
凍結 event.persisted が true、 freeze イベントが続く)
終了 event.persisted が false、 unload イベントが続く)

beforeunload

ウィンドウ、ドキュメント、およびそのリソースがアンロードされます。 ドキュメントは引き続き表示され、この時点ではイベントをキャンセルできます。

重要: beforeunload イベントは、保存されていない変更をユーザーに警告する場合にのみ使用してください。変更を保存すると、イベントは削除されます。無条件にページに追加することは絶対に避けてください。そうすると、パフォーマンスが低下する場合があります。詳細については、レガシー API のセクションをご覧ください。

考えられる以前の状態:
非表示

現在の状態の例:
terminated

unload

ページがアンロードされている。

警告: unload イベントは信頼性が低く、パフォーマンスが低下する可能性があるため、使用はおすすめしません。詳しくは、以前の API のセクションをご覧ください。

考えられる以前の状態:
非表示

現在の状態の可能性:
terminated

* Page Lifecycle API で定義された新しいイベントを示します。

Chrome 68 で追加された新機能

上のグラフは、ユーザーが開始するものではなく、システムによって開始される「フリーズ」と「破棄」の 2 つの状態を示しています。前述のように、現在のブラウザでは、非表示のタブが(ブラウザの判断で)フリーズして破棄されることがありますが、デベロッパーがそのタイミングを把握する方法はありません。

Chrome 68 では、documentfreeze イベントと resume イベントをリッスンすることで、非表示のタブのフリーズとロック解除の状態を確認できるようになりました。

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

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

Chrome 68 以降、パソコン版 Chrome の document オブジェクトに wasDiscarded プロパティが追加されました(Android のサポートは、こちらの問題で追跡されています)。非表示のタブでページが破棄されたかどうかを確認するには、ページの読み込み時にこのプロパティの値を検査します(注: 破棄されたページを再度使用するには、リロードする必要があります)。

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

freeze イベントと resume イベントで行うべき重要なことや、破棄されるページを処理して準備する方法については、各状態に関するデベロッパー向けの推奨事項をご覧ください。

以降のセクションでは、これらの新機能が既存のウェブ プラットフォームの状態とイベントにどのように適合するかについて概要を説明します。

コードでページのライフサイクルの状態を監視する方法

アクティブパッシブ非表示の状態では、既存のウェブ プラットフォーム API から現在のページ ライフサイクルの状態を決定する JavaScript コードを実行できます。

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

一方、凍結状態と終了状態は、状態が変化するときに、それぞれのイベント リスナー(freezepagehide)でのみ検出できます。

状態変化をモニタリングする方法

前に定義した 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);

このコードは次の 3 つのことを行います。

  • getState() 関数を使用して初期状態を設定します。
  • 次の状態を受け取り、変更があった場合に状態の変更をコンソールにログに記録する関数を定義します。
  • 必要なすべてのライフサイクル イベントのキャプチャ イベント リスナーが追加されています。これにより、logStateChange() が呼び出され、次の状態に渡されます。

このコードで注意すべき点は、すべてのイベント リスナーが window に追加され、すべて {capture: true} を渡すことです。これには次のような理由があります。

  • ページのライフサイクル イベントのターゲットはすべて同じではありません。pagehidepageshowwindow で、visibilitychangefreezeresumedocument で、focusblur はそれぞれの DOM 要素でトリガーされます。
  • これらのイベントのほとんどはバブルしません。つまり、キャプチャしないイベント リスナーを共通の祖先要素に追加して、それらをすべて監視することはできません。
  • キャプチャ フェーズはターゲット フェーズまたはバブル フェーズより前に実行されるため、そこにリスナーを追加すると、他のコードがリスナーをキャンセルする前にリスナーが実行されるようになります。

各州におけるデベロッパー向けの推奨事項

デベロッパーは、ページのライフサイクルの状態を理解し、コードでその状態を監視する方法を理解することが重要です。行うべき作業(および行わないべき作業)の種類は、ページの状態に大きく依存するためです。

たとえば、ページが非表示の状態である場合に、ユーザーに一時的な通知を表示することは明らかに意味がありません。この例は非常に明白ですが、他にも列挙する価値のある、あいまいな推奨事項があります。

デベロッパー向けの推奨事項
Active

アクティブ状態はユーザーにとって最も重要な時間であるため、ページがユーザー入力に応答する最も重要な時間です。

メインスレッドをブロックする可能性がある UI 以外の処理は、アイドル状態に優先度を下げるか、Web Worker にオフロードする必要があります。

Passive

パッシブ状態では、ユーザーはページを操作していませんが、引き続きページを表示できます。つまり、UI の更新とアニメーションは引き続きスムーズに行われる必要がありますが、これらの更新が発生するタイミングは重要ではありません。

ページがアクティブからパッシブに変わったら、保存されていないアプリの状態を保持するのが適切なタイミングです。

Hidden

ページが非アクティブから非表示に変更されると、ページが再読み込みされるまでユーザーがそのページを操作しなくなる可能性があります。

非表示への遷移は、デベロッパーが確実に検出できる最後の状態変化である場合もあります(これは特にモバイルの場合に当てはまります。ユーザーがタブやブラウザ アプリ自体を閉じることができ、そのような場合、beforeunloadpagehideunload イベントは発生しません)。

つまり、非表示状態は、ユーザー セッションの最終的な終了として扱う必要があります。つまり、保存されていないアプリケーションの状態を保持し、送信されていないアナリティクス データを送信します。

また、UI の更新を停止し(ユーザーには表示されないため)、ユーザーがバックグラウンドで実行したくないタスクをすべて停止する必要があります。

Frozen

凍結状態の場合、タスクキュー内のフリーズ可能なタスクは、ページがフリーズ解除されるまで一時停止されます。ページが破棄された場合など、フリーズ解除されないこともあります。

つまり、ページが非表示から固定に変わった場合は、タイマーを停止するか、接続を解除することが不可欠です。固定されている場合、同じオリジンで開いている他のタブに影響するか、 バックフォワード キャッシュにページを保存するブラウザの機能に影響する可能性があります。

特に、次のことを行ってください。

  • 開いている IndexedDB 接続をすべて閉じます。
  • 開いている BroadcastChannel 接続を閉じます。
  • アクティブな WebRTC 接続を閉じます。
  • ネットワーク ポーリングを停止するか、開いている Web Socket 接続をすべて閉じます。
  • 保留中のウェブロックを解除します。

また、動的ビューの状態(無限リストビューのスクロール位置など)を sessionStorage(または commit() を介した IndexedDB)に保持し、ページが破棄されて後で再読み込みされた場合に復元できるようにする必要があります。

ページがフリーズから非表示に戻った場合、閉じた接続を再度開くか、ページが最初にフリーズされたときに停止したポーリングを再開できます。

Terminated

通常、ページが終了状態に移行しても、特に必要な対応はありません。

ユーザー操作の結果としてページがアンロードされると、常に非表示状態を経て終了状態に入るため、非表示状態はセッション終了ロジック(アプリケーション状態の保持やアナリティクスへのレポートなど)を実行する場所です。

また(非表示状態に関する推奨事項で説明されているように)、多くの場合(特にモバイルの場合)終了状態への遷移を信頼性を持って検出できないため、終了イベント(beforeunloadpagehideunload など)に依存しているデベロッパーはデータを失う可能性があります。

Discarded

ページが破棄される時点で、デベロッパーは [破棄済み] ステータスを検出できません。これは、通常、ページはリソース制約下で破棄されるためです。破棄イベントに応じてスクリプトを実行できるようにするためだけにページをフリーズ解除することは、ほとんどの場合不可能です。

そのため、[非表示] から [凍結] への変更で破棄される可能性に備え、document.wasDiscarded をチェックすることで、ページの読み込み時に破棄されたページの復元に対応できます。

繰り返しになりますが、ライフサイクル イベントの信頼性と順序はすべてのブラウザで一貫して実装されているわけではないため、表のアドバイスに従う最も簡単な方法は PageLifecycle.js を使用することです。

以前のライフサイクル API で

次のイベントは、可能な限り回避する必要があります。

アンロード イベント

多くのデベロッパーは、unload イベントを保証付きのコールバックとして扱い、セッション終了シグナルとして使用して状態を保存し、分析データを送信しています。しかし、特にモバイルでは、これは非常に信頼性に欠ける方法です。unload イベントは、モバイルのタブ切り替えツールからタブを閉じたり、アプリ切り替えツールからブラウザアプリを閉じたりなど、多くの一般的なアンロード状況では発生しません。

そのため、セッションの終了を判断するには常に visibilitychange イベントを使用し、非表示状態をアプリとユーザーデータを保存する最後の信頼できるタイミングと見なすことをおすすめします。

さらに、登録された unload イベント ハンドラ(onunload または addEventListener() を介して)が存在するだけで、ブラウザがページをバックフォワード キャッシュに保存できなくなり、前後のページの読み込みが遅くなる可能性があります。

すべての最新ブラウザでは、unload イベントではなく、pagehide イベントを使用して、ページのアンロード(終了状態)の可能性を常に検出することをおすすめします。Internet Explorer バージョン 10 以前をサポートする必要がある場合は、pagehide イベントを検出し、ブラウザが pagehide をサポートしていない場合にのみ unload を使用する必要があります。

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 イベント

beforeunload イベントには unload イベントと同様の問題があります。これまで、beforeunload イベントが存在すると、ページがバックフォワード キャッシュの対象から除外される可能性があるためです。最新のブラウザにはこのような制限はありません。ただし、一部のブラウザでは、予防措置として、ページを「前へ」または「後へ」キャッシュに保存しようとしたときに beforeunload イベントを発生させません。つまり、このイベントはセッション終了シグナルとして信頼できません。また、一部のブラウザ(Chrome を含む)では、beforeunload イベントを発生させる前にページでのユーザー操作が必要になるため、信頼性にさらに影響します。

beforeunloadunload の違いの 1 つは、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.
    return (event.returnValue = true);
  }
});

代わりに、次のようにします(これは、beforeunload リスナーを必要な場合にのみ追加し、必要でない場合に削除するためです)。

const beforeUnloadListener = (event) => {
  event.preventDefault();
  
  // Legacy support for older browsers.
  return (event.returnValue = true);
};

// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
  addEventListener('beforeunload', beforeUnloadListener);
});

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

よくある質問

「読み込み中」の状態が表示されないのはなぜですか?

Page Lifecycle API は、互いに独立して相互に排他的な状態を定義します。ページの読み込みはアクティブ、パッシブ、非表示のいずれの状態でも可能で、読み込みが完了する前に状態を変更したり終了したりすることがあるため、このパラダイムでは個別の読み込み状態は意味をなしません。

非表示のときに重要な処理を行うページが、フリーズまたは破棄されないようにするにはどうすればよいですか?

ウェブページが非表示状態で実行されている間は、フリーズすべき正当な理由があります。最もわかりやすい例は、音楽を再生するアプリです。

また、Chrome がページを破棄することが危険な場合もあります。たとえば、送信されていないユーザー入力を含むフォームが含まれている場合や、ページのアンロード時に警告する beforeunload ハンドラが含まれている場合などです。

現時点では、Chrome はページを破棄する際には慎重に行動しており、ユーザーに影響しないことが確実な場合にのみ破棄します。たとえば、非表示状態で次のいずれかの操作が確認されたページは、リソースの制約が厳しい場合を除いて破棄されません。

  • 音声を再生しています
  • WebRTC の使用
  • テーブルのタイトルまたはファビコンの更新
  • アラートの表示
  • プッシュ通知の送信

タブを安全に凍結または破棄できるかどうかの判断に使用される現在のリスト機能については、Chrome のフリーズと破棄のヒューリスティックをご覧ください。

バックフォワード キャッシュとは何ですか?

バックフォワード キャッシュは、一部のブラウザで実装されている、戻るボタンと進むボタンの使用を高速化するナビゲーションの最適化を表す用語です。

ユーザーがページから移動すると、これらのブラウザはそのページのバージョンをフリーズします。これにより、ユーザーが戻るボタンまたは進むボタンを使用して戻ってきた場合に、ページをすばやく再開できます。unload イベント ハンドラを追加すると、この最適化が不可能になります

あらゆる目的において、このフリーズは、CPU やバッテリーを節約するためにブラウザが行うフリーズと同じ機能です。そのため、このフリーズはライフサイクル状態の凍結の一部と見なされます。

非同期 API をフリーズ状態または終了状態のときに実行できない場合、IndexedDB にデータを保存するにはどうすればよいですか?

フリーズ状態と終了状態では、ページのタスクキュー内のフリーズ可能なタスクは一時停止されます。つまり、IndexedDB などの非同期のコールバック ベースの API は確実に使用できなくなります。

今後、IDBTransaction オブジェクトに commit() メソッドを追加する予定です。これにより、デベロッパーはコールバックを必要としない書き込み専用トランザクションを効果的に実行できるようになります。つまり、デベロッパーが IndexedDB にデータを書き込むだけで、読み取りと書き込みからなる複雑なトランザクションを実行していない場合、タスクキューが停止する前に commit() メソッドを完了できます(IndexedDB データベースがすでに開いていることを前提としています)。

ただし、すぐに動作する必要があるコードについては、デベロッパーには次の 2 つの方法があります。

  • セッション ストレージを使用する: セッション ストレージは同期であり、ページの破棄後も保持されます。
  • Service Worker から IndexedDB を使用する: Service Worker は、ページが終了または破棄された後に IndexedDB にデータを保存できます。freeze または pagehide イベント リスナーで、postMessage() を介して Service Worker にデータを送信できます。Service Worker は、データを保存できます。

アプリをフリーズ状態と破棄状態の両方でテストする

アプリがフリーズ状態と破棄状態のときにどのように動作するかをテストするには、chrome://discards にアクセスして、開いているタブを実際にフリーズまたは破棄します。

Chrome の破棄 UI
Chrome の破棄 UI

これにより、ページが破棄後に再読み込みされたときに、freeze イベントと resume イベント、および document.wasDiscarded フラグを正しく処理できます。

概要

ユーザーのデバイスのシステム リソースを尊重したいデベロッパーは、ページのライフサイクルの状態を考慮してアプリを作成する必要があります。ユーザーが予想していなかった状況で、ウェブページがシステム リソースを過剰に消費しないようにすることが重要です。

デベロッパーが新しい Page Lifecycle API の実装を開始すればするほど、ブラウザが使用されていないページをフリーズして破棄することが安全になります。つまり、ブラウザのメモリ、CPU、バッテリー、ネットワーク リソースの消費量が削減され、ユーザーにとってメリットがあります。