ブラウザーのストレージ制限と削除基準
クライアント側 (すなわちローカルディスク) に何らかのデータを保存するウェブ技術は何種類かがあります。ブラウザーがどれだけの容量をウェブデータストレージに割り当てるかや、容量の上限に達したときにどのデータを削除するかのプロセスは単純ではなく、またブラウザーにより異なります。この記事では、必要なローカルストレージの容量を確保するために、いつどのローカルコンテンツを破棄するのかをどうやって特定するのかを説明します。
ブラウザーのデータストレージを使用する技術は何か?
Firefox では以下の技術が、必要なデータを保存するためにブラウザーのデータストレージを使用します。ここではこれらの技術を「クォータクライアント」と呼びます。
メモ: Firefox では、ウェブストレージもまもなく同じストレージ管理ツールを使い始めます。それはこの文書で記述します。
メモ: プライベートブラウジングモードは、大半のデータストレージに対応していません。ローカルストレージのデータと Cookie は保存されますが、短命です。 — 最後のプライベートブラウジングウィンドウを閉じた時にデータは消去されます。
オリジンの「最終アクセス日時」はこれらのうちの何れかがアクティブ化/非アクティブ化されたときに更新されます。オリジン立ち退き (origin eviction) によって、すべてのクォータクライアントでデータ削除が行われたときに更新されます。
Chrome/Opera では、 Quota Management API が IndexedDB、Web SQL(非推奨)、ファイルとディレクトリー項目 API のクォータ管理を制御しています。
さまざまな種類のデータストレージ
同じブラウザー内で同じ保存方法を使用していても、解釈されるデータストレージの種類はさまざまです。この章では、さまざまなブラウザーで見つけられる多様なストレージについて説明します。
ストレージは 2 種類に分けられます。
- 永続的なもの。長期間保存されることを意図したデータです。これは、ユーザーが選択した場合にのみ削除されます (たとえば、Firefox では、設定に進み、プライバシーとセキュリティ > Cookie とサイトデータのオプションを使用することで、すべての保存データを削除するか、または選択したオリジンからの保存データのみを削除するかを選択できます)。
- 一時的なもの。長期間にわたって維持する必要がないデータです。ストレージの容量制限に達すると、 LRU ポリシーによりもっとも古く使用されたものから削除されます。
Firefox では、永続的なストレージが使用されると、ユーザーにはデータが永続的になることを警告するポップアップが表示され、それが良いかどうかを尋ねます。一時的データストレージは明示的にユーザーにプロンプトを表示しません。
ストレージは既定では一時的です。開発者は Storage API で利用できる StorageManager.persist()
メソッドを使用して永続的なストレージにすることができます。
データの保存先は?
それぞれのストレージ種別は、個別のリポジトリーを表します。以下は、ユーザーの Firefox プロファイル下のディレクトリにおける実際のマッピングです (他のブラウザーでは若干異なる場合があります)。
<profile>/storage
— クォータマネージャー (後述) に管理されている、ストレージの主要な最上位ディレクトリーです。<profile>/storage/permanent
— 永続的なデータストレージのリポジトリーです。<profile>/storage/temporary
— 一時的なデータストレージのリポジトリーです。<profile>/storage/default
— 既定のデータストレージのリポジトリーです。
メモ: ストレージ API の導入後は、"permanent" フォルダーは廃止されると考えられます。"permanent" フォルダーは IndexedDB の永続的な種類のデータベースのみ保存します。ボックスモードが "best-effort" や "persistent" であっても、データは <profile>/storage/default 以下に保存されます。
メモ: Firefox では URL バーに about:support
と入力して移動して、プロファイルフォルダー の隣にある フォルダーを開く ボタン (macOS では Finder で開く) を押下すると、プロファイルのフォルダーを見つけることができます。
メモ: プロファイルフォルダーでデータを保存する場所を見ていると、第 4 のフォルダー persistent
が見つかるかもしれません。本来は更新や移行を単純化するため、少し前に persistent
フォルダーを permanent
フォルダーに改名しました。
メモ: ユーザーが <profile>/storage
の配下に、独自のディレクトリーやファイルを作成すべきではありません。このようなことを行うと、ストレージの初期化に失敗します。例えば、open()
でエラーイベントが発生します。
ストレージの制限
ブラウザーのストレージの最大容量は動的であり、ハードドライブのサイズに応じて変わります。グローバルリミットはディスクの空き容量の 50% に決められます。Firefox では、クォータマネージャーと飛ばれる内部のブラウザーツールがオリジンごとにどれだけディスク容量を使用しているかを絶えず注視しており、必要に応じてデータを削除します。
従ってハードドライブの空き容量が 500GB であれば、ブラウザーの合計ストレージサイズは 250GB になります。上限に達するとオリジン立ち退き (origin eviction) と呼ばれる処理を実行して、ストレージの総量が再び上限を下回るまで、オリジン全体に相当するデータを削除します。オリジン内の一部分を削除するような縮小法はありません。オリジン内のデータベースをひとつだけ削除すると、矛盾が発生するおそれがあります。
また、グループリミットというもうひとつの制限もあります。これは、グローバルリミットの 20% として定義されます。それぞれのオリジンは、グループ (オリジンのグループ) の一部です。グループは、eTLD+1 ドメインごとに 1 つ作られます。例えば次の通りです。
mozilla.org
— グループ 1、オリジン 1www.mozilla.org
— グループ 1、オリジン 2joe.blogs.mozilla.org
— グループ 1、オリジン 3firefox.com
— グループ 2、オリジン 4
このグループでは mozilla.org
、www.mozilla.org
、joe.blogs.mozilla.org
が、合わせてグローバルリミットの 20% を上限としてストレージを使用できます。firefox.com
は、別に 20% の上限を持ちます。
これら 2 種類の制限は、制限に達したときの動作が異なります。
- グループリミットは「ハードリミット」とも呼ばれます。オリジン立ち退きを発生させません。
- グローバルリミットは、いくらかの領域が解放されて処理を継続できる可能性がありますので「ソフトリミット」です。
メモ: グループリミットは、上記で触れた最小のグループリミットにかかわらず、グローバルリミットより大きくすることはできません。グローバルリミットが 8MB といった本当にメモリーが少ない状況では、グループリミットも 8MB となります。
メモ: グループリミットに達したとき、あるいはオリジン立ち退きで十分な空き容量を確保できないときは、ブラウザーで QuotaExceededError
が発生します。
メモ: Chrome では、ソフトおよびハードのストレージのクォータの限界が M66 から変更されました。詳しい情報はこちらにあります。
LRU ポリシー
使用可能なディスク領域がすべて埋まったときは、クォータマネージャーが LRU ポリシーに基づいてデータの削除処理を始めます。もっとも過去に使用されたオリジンのデータが始めに削除され、上限に達しなくなるなるまで削除を繰り返します。
一時的なストレージを使用して、オリジンごとに「最終アクセス日時」を記録しています。一時的なストレージがグローバルリミットに達する (後に上限をさらに超える) と、現在使用していない (すなわち、データストアを開き続けているタブやアプリがない) オリジンをすべて発見しようとします。これらは、「最終アクセス日時」によって整列されます。オリジン立ち退きを発生させたリクエストを満たすのに十分な領域を確保するまで、もっとも過去に使用されたオリジンを削除し続けます。
関連情報
- Working with quota on mobile browsers, by Eiji Kitamura モバイルブラウザーのクライアント側ストレージについて詳しく分析した記事。
- ウェブのストレージ