OpenPWAStore
返回 News
Guide · May 19, 2026

你的 PWA 生存取决于存储配额行为

如何管理存储配额、测试驱逐行为、为已安装 PWA 请求持久化存储。

OpenPWA Editorial2 min read
你的 PWA 生存取决于存储配额行为 cover

为什么存储配额会破坏 PWA

你的 PWA 支持离线工作。用户在 IndexedDB 中存储文档、缓存图片、保存草稿。一切正常。

然后浏览器存储空间耗尽了。浏览器开始驱逐数据以腾出空间。IndexedDB 数据库被部分删除。缓存条目消失。用户丢失了工作成果,看到损坏的界面,然后卸载你的应用。

问题所在:超出配额时不会产生清晰的错误。取而代之的是,浏览器开始驱逐数据,"如无信号供 service worker 反应",根据一篇关于处理 service worker 更新的 PWA 实现指南所述。

浏览器的存储模型

现代浏览器使用按 origin 的存储配额,适用于 IndexedDB、Cache API 和其他存储 API。实际限制因浏览器、设备和存储压力而异:

  • Chrome:每个 origin 通常为可用磁盘空间的 60-80%
  • Safari:桌面端通常每个 origin 为 1 GB,移动端更少
  • Firefox:与 Chrome 类似,但有平台特定的调整
  • 移动浏览器:显著更低的限制,通常每个 origin 为 50-250 MB

添加到桌面的已安装 PWA 会获得更好的待遇——在像 Safari 这样的一些浏览器中,它们不受适用于普通 Web 应用的七天限制。但它们不受存储压力的豁免。

存储估算

写入数据前,估算使用量:

const { usage, quota } = await navigator.storage.estimate();
const usageMB = usage / (1024 * 1024);
const quotaMB = quota / (1024 * 1024);
const usedPercent = (usage / quota) * 100;

console.log(`已使用 ${usageMB.toFixed(2)} MB / ${quotaMB.toFixed(2)} MB (${usedPercent.toFixed(1)}%)`);

安全注意:遥测和指纹识别

存储估算会显示磁盘使用模式,这可能成为一个较弱的指纹识别向量。未经用户同意,不要在生产环境中记录精确大小。改用百分比范围(例如"使用 10-20% 配额"),既能减少指纹识别风险,又能提供有用的反馈。

持久化存储工作流

持久化存储告诉浏览器"除非用户明确删除,否则不要驱逐这些数据"。这不是对所有驱逐的绝对保证,但会在存储耗尽时将你的 PWA 排在前面。

请求持久化存储

async function requestPersistentStorage() {
  if (navigator.storage && navigator.storage.persist) {
    const persisted = await navigator.storage.persist();
    if (persisted) {
      console.log('存储现在是持久的');
    } else {
      console.log('存储不是持久的');
      // 浏览器拒绝了请求——引导用户清理空间或重新考虑
    }
  }
}

// 用户安装你的 PWA 后或完成入职引导后
requestPersistentStorage();

何时请求:许可框架

不要在页面加载时立即请求持久化存储。浏览器会拒绝它。取而代之:

  1. 解释原因"我们将你的文档存储在本地,以便你可以离线工作。这需要设备上的永久存储。"
  2. 在用户有意的行动后请求:用户安装你的 PWA、启用离线模式或创建第一个文档时。
  3. 提供替代方案:如果用户拒绝,提供云同步而非本地存储。

平台差异

| 浏览器 | 持久化存储行为 | 备注 | |--------|---------------|------| | Chrome | 请求会显示权限提示 | 用户可以拒绝存储配额请求 | | Safari | 自动授予给已安装的 Web 应用 | iOS PWA"添加到主屏幕"启用持久化 | | Firefox | 与 Chrome 类似,有提示 | 可能需要先有用户交互 | | Edge | 遵循 Chromium 行为 | 与 Chrome 一致 |

驱逐测试清单

发布前,测试 PWA 在存储耗尽时的行为:

设置测试环境

  1. 使用 Chrome DevTools > Application > Storage 查看当前使用情况
  2. 手动用虚拟数据填满存储直到配额接近满
  3. 监控 IndexedDB 错误和缓存失败

测试场景

  • [ ] 配额超出时尝试写入 IndexedDB
  • [ ] 驱逐后导航到缓存过的离线页面
  • [ ] 用适当的错误处理重试失败的缓存写入
  • [ ] 为"存储已满"显示用户友好的消息,而非通用错误
  • [ ] 部分驱逐后验证数据完整性(某些条目幸存,其他条目不有效)

恢复工作流

检测到配额超限或数据丢失时:

  1. 通知用户:"你的设备存储空间不足。某些本地数据可能不可用。"
  2. 提供清晰的行动:"清除缓存图片"或"启用云同步"
  3. 优雅降级功能:允许只读访问,建议重新下载数据
  4. 不要静默失败:将配额错误记录到错误跟踪中,但始终显示用户消息

生产环境中会出现什么问题

常见错误

  1. 忽略配额:无上限的 IndexedDB 永远增长,直到浏览器驱逐所有内容
  2. 没有错误处理:脚本抛出 QuotaExceededError 并导致页面崩溃
  3. 静默数据丢失:缓存成功回调永远不会触发,但 UI 显示缓存内容
  4. 按用户假设:你的设备上 500 MB 没问题,但你的用户只有 64 MB

现实世界失败模式

用户在手机上打开你的 PWA。他们下载了 20 个 PDF 文档(200 MB)。你在每次页面导航时缓存所有图片(150 MB)。配额达到 250 MB。浏览器驱逐最旧的缓存条目。用户导航回去。图片丢失。用户看到损坏的 UI。你的 PWA 失去了一个用户。

生产 PWA 的最佳实践

  1. 智能缓存:对关键资源(应用壳)采用缓存优先,对动态内容采用网络优先。不要永远缓存所有内容。
  1. 在分析中监控存储使用情况:按设备类型跟踪中位数/四分位数存储使用情况。如果 25% 的移动用户达到 >80% 的配额,减少缓存限制。
  1. 使用缓存清理:更新缓存时,删除旧版本而不是累积它们。为媒体资产实施缓存过期。
  1. 提供用户控制:让用户从设置中清除缓存数据。清楚显示 PWA 使用了多少空间。
  1. 在低存储设备上测试:在 Chrome DevTools 中模拟 64 MB、128 MB、256 MB 存储限制。不要假设用户有充足的存储。

这对你的 PWA 架构意味着什么

存储管理不是功能,而是架构。你的离线策略必须考虑到:

  • 每个平台的配额限制
  • 压力下的驱逐行为
  • 持久化存储许可流程
  • 数据不可用时的优雅降级

如果你在构建文档编辑器,考虑:

  • 默认本地优先,云同步作为回退
  • 支持部分文档(缓存结构,按需加载内容)
  • 用户引导的缓存管理(清除旧草稿,归档未使用的文件)

如果你在构建媒体应用,考虑:

  • 渐进式加载(缓存前几项,流式传输其余项)
  • 媒体缓存 30 天后过期
  • 可选的高质量下载,需要明确的用户操作

下一步

存储配额管理是更大的离线就绪策略的一部分。下一部分是后台同步——将离线操作排队,并在连接恢复时重放。与配额感知缓存和优雅降级结合,后台同步将离线从回退模式转变为一等特性。

不要让存储限制破坏你的 PWA 承诺。估算、监控、持久化、测试。即使浏览器决定另有安排,用户也期望他们的数据能够存活。