乐趣区

关于javascript:浏览器有几种储存机制讲一讲Storage-for-the-Web

前言

明天咱们来讲一讲 Web 存储有几种机制,并弄清楚什么是长期存储,什么是长久存储。

你可能不晓得的是:咱们平时口中所说的长久存储 localStorage 很多时候其实是零碎级别的“长期存储”。

注释

IndexedDB

Indexed DB 的操作是异步的,不会阻塞主线程的执行,能够在 window、web workers、service workers 环境中应用。

IndexedDB 是基于文件存储的,API 较为简单,蕴含 v1 v2 的差别,倡议通过类库来应用,比方:Dexie.js。

Cache Storage API

Cache Storage API 为缓存的 Request/Response 对象提供存储机制,常在 ServiceWorker 中利用。

异步,不会阻塞主线程的执行,能够在 window、web workers、service workers 环境中应用。

SessionStorage

同步,会阻塞主线程的执行。

个别用于贮存临时性的大量的数据。

SessionStorage 是标签级别的,跟随者标签的生命周期,并且会随着标签的销毁而清空数据。

无奈在 web workers、service workers 环境中应用。

它只能贮存字符串,大小限度大概为 5MB。

LocalStorage

同步,会阻塞主线程的执行。

无奈在 web workers、service workers 环境中应用。

它只能贮存字符串,大小限度大概为 5MB。

Cookies

Cookies 有它的用处,但不适用于贮存数据。

Cookie 会在每次 HTTP 申请的时候携带在申请头中,大体积的 Cookies 会显著减少 HTTP 申请的累赘。

Cookies 读写是同步的,只能贮存字符串,并且无奈在 web workers 环境中应用。

File System API

File System API 和 FileWriter API 提供读取或写入文件到沙箱中(Sandboxed file system)。

它是异步的,不举荐应用,因为 File System API 只能在 Chromium 内核中应用。

File System Access API

File System Access API 设计用于便捷得读取和编辑本地文件。

但在读取或写入本地文件的时候,须要取得用户受权,并且受权状态无奈长久化记录。

Application Cache

Application Cache 已被弃用,不倡议应用。

倡议迁徙至 service workers 或 Cache API。

Storage 能够应用多少磁盘空间?

  • Chrome 容许应用 80% 的硬盘空间,繁多的源(域名)能够应用 60% 的硬盘空间,能够通过 StorageManager API 检测最大的硬盘空间限额,其余基于 Chromium 内核的浏览器有不一样的限度,可能会容许应用更多的硬盘空间,查看更多实现 PR #3896
  • Internet Explorer 10(IE 10)及以上,最多能够贮存 250MB,并在超过 10MB 的时候会提醒用户
  • Firefox 容许应用 50% 的闲暇硬盘空间,单个一级域名最多能够应用 2GB 硬盘空间,能够通过 StorageManager API 检测最大的硬盘空间限额
  • Safari 容许应用 1GB,当达到 1GB 的时候会提醒用户(该数据可能不精确,没有找到 Safari 官网文档)

古代浏览器大多数曾经不会再提醒用户以受权更多的贮存空间了。

如何检测贮存空间是否可用?

在大多数浏览器中,能够通过 StorageManager API 检测贮存空间总量与正在应用的量

if (navigator.storage && navigator.storage.estimate) {const quota = await navigator.storage.estimate();
  // quota.usage -> Number of bytes used.
  // quota.quota -> Maximum number of bytes available.
  const percentageUsed = (quota.usage / quota.quota) * 100;
  console.log(`You've used ${percentageUsed}% of the available storage.`);
  const remaining = quota.quota - quota.usage;
  console.log(`You can write up to ${remaining} more bytes.`);
}
// quota data
{
  "quota": 299977904946,
  "usage": 27154039,
  "usageDetails": {
    "caches": 26813093,
    "indexedDB": 305864,
    "serviceWorkerRegistrations": 35082
  }
}

留神:

  1. 并不是所有浏览器都实现了,因而应用之前须要先判断兼容性
  2. 须要捕捉并解决超过配额限额的谬误

IndexedDB 超限解决

indexedDB 超限将会执行 onabort 回调,并抛出一个 DOMException 谬误,须要解决它的 QuotaExceededError 异样。

const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
  const error = event.target.error; // DOMException
  if (error.name == 'QuotaExceededError') {// Fallback code goes here}
};

Cache API 超限解决

抛出一个 Promise Rejection,QuotaExceededError 谬误对象,须要解决它的 QuotaExceededError 异样。

try {const cache = await caches.open('my-cache');
  await cache.add(new Request('/sample1.jpg'));
} catch (err) {if (error.name === 'QuotaExceededError') {// Fallback code goes here}
}

浏览器什么时候回收存储空间?

Web Storage 分为两种贮存模式,别离是:长期存储 Best Effort 和长久存储 Persistent。

默认状况下网站数据(包含 IndexedDB, Cache API, LocalStorage 等)都贮存在长期存储 Best Effort 中,会在存储空间有余的时候被浏览器革除掉。

各个浏览器回收存储空间的差别:

  • Chrome 当浏览器存储空间有余时,会优先革除最近起码应用的数据,一一革除,直至不再超限
  • IE 10+ 不会主动革除数据,但会阻止站点持续写入数据
  • Firefox 当磁盘空间充斥时,会优先革除最近起码应用的数据,一一革除,直至不再超限
  • Safari(iOS、iPadOS、MacOS)会主动革除超过 7 天以上的数据,但不会革除“已增加至主屏幕”的网站和“PWA”网站

申请和查看长久存储 Persistent Storage

申请长久存储 Persistent Storage:

// Request persistent storage for site
if (navigator.storage && navigator.storage.persist) {const isPersisted = await navigator.storage.persist();
  console.log(`Persisted storage granted: ${isPersisted}`);
}

查看长久存储 Persistent Storage 受权状态:

// Check if site's storage has been marked as persistent
if (navigator.storage && navigator.storage.persist) {const isPersisted = await navigator.storage.persisted();
  console.log(`Persisted storage granted: ${isPersisted}`);
}

各个浏览器申请长久存储 Persistent Storage 的差别:

  • 在 Chrome 55 当前,申请长久存储只须要满足以下任一条件,即可主动取得长久存储权限,无需用户确认:

    • 该站点已增加书签, 并且用户的书签数小于等于 5 个
    • 站点有很高的 ”site engagement”,通过这个命令能够查看: chrome://site-engagement/
    • 站点已增加到主屏幕
    • 站点启用了 push 告诉性能
  • 在 Firefox 中,会提醒用户受权

最初测试并验证:

  1. 关上 https://baidu.com,关上控制台输出 await navigator.storage.persist(),返回 true
  2. 关上 https://wy.guahao.com,关上控制台输出 await navigator.storage.persist(),返回 false

参考文献

  • 《Storage for the web》
  • 《Persistent storage》
退出移动版