原文链接:https://love2dev.com/blog/what-is-the-service-worker-cache-storage-limit/undefined作者:Chris Loveundefined时间:2019.04.04
Cache API
是Service Worker
实现离线访问的基础,因此需要开发者设计站点资源持久化存储的逻辑。
这篇文章能够帮助开发者解决在规划缓存策略时遇到的诸多挑战。
Browser Service Worker Cache Capacity
Cache
最多是多少?我的应用最少需要多少?
页面资源有很多种形式,比较常见的有HTML、CSS、Javascript、images和字体文件。这些都被归类为URL可寻址资源,意思是你可以通过在浏览器的地址栏输入URL来获取这个文件。
以域名为维度会被赋予一定的可用空间来做一些事情。可用空间被该域名下所有类型的存储共享,例如:LocalStorage、IndexedDB、Filesystem,当然也包括了Caches。Service Worker用于缓存的空间并没有在规范中被定义。具体的大小取决于浏览器并依赖于设备和存储条件。
文件不是唯一可以缓存的内容。localStorage就非常适合保存值为字符串的键值对;IndexedDB则更强大,可以有效地存储更多类型的数据,我认为它是浏览器中的轻量级文档数据库。appCache和service worker能够持久化地缓存URL可寻址资源的文件,这在技术上是正确的。
但是service worker cache不是唯一一个需要注意的浏览器存储介质。除了service worker cache的大小限制外,你有没有想过下面的问题:
当然你也可以算上appCache,但是如果你注册了service worker这就没什么意义了。另外,所有的浏览器都弃用了appCache。
你得到了多少空间?你知道这些空间用完后会发生什么么?
好消息是你应该会有足够的空间来存储你需要的资源依次确保你的网站能够脱机工作,除非你的网站很臃肿或者包含了大量的页面和图片。
在浏览器分配可用空间是已经确定了常见的模式,当然这种行为可能会因浏览器的变化而变化。
在9月的Microsoft Edge开发者峰会上,Ali Alabbas分享了浏览器在分配存储空间时达成了共识的一般规则。
存储量取决于客户设备可用的磁盘空间大小。一般范围是50MB到20GB,但是兴奋归兴奋你任然应该妥善去使用。
通用规则是可用空间的20%或按照以下规则:
注意,不要通过移动网络来缓存页面资源,当你计划通过移动数据缓存整个网站时,你的用户一定不会感谢你。这就是为什么Amazon不通过service worker来缓存整个网站的主要原因。
Microsoft Edge、FireFox、Chrome和Opera往往都遵循这个规则。
我设计缓存策略时的前提就是当前移动设备占据了绝大多数网络流量。普通消费者的移动设备大致相当于Nexus 5手机,一旦安装了大型笨重的应用程序,并考虑到照片,视频和音乐下载,普通设备几乎没有可用空间。
天哪!苹果公司为什么要将事情搞得这么复杂?
Service Worker缓存规范的一个缺点是缺乏限制容量或存储的规则或算法,这意味着每个浏览器厂商都会自己定义缓存限制和失效策略。
苹果公司目前的为Service Worker制定的缓存限制是50MB,准确来说限制在50MiB,相当于约52MB。它也按“分区”分配,这是一种与iFrame相关的复杂概念。
但故事并没有就此结束。从表面上看,缓存的有效期不会超过两周。
苹果公司实现PWA持久性的方式很奇怪。如果在几周内未使用的PWA(我们认为它是2周),iOS设备会清除存储的资源。
这样做对用户友好不友好尚无定论,但对于使用service worker来提供更好的用户体验的企业来说绝对算不上友好。
如果你想了解为什么苹果要这么做,要知道对他们来说这也不是什么新鲜事。长久以来,在缓存的限制上他们都非常激进。他们试图在限制缓存方面出错,以确保设备具有足够可用的存储空间。
当然,如果你知道iOS上原生应用的大小,你应该会理解他们为什么这么做。毕竟原生应用太大了。
这意味着您需要进行相应的计划。虽然大多数网站都没有50MB存储限制的问题,但有些网站会有。
但是50MB,你能做什么?
我一般会在服务工作者中实现某种失效规则,这就意味着我的PWA具有可控制的缓存,不会达到配额限制。我讨厌为特定的浏览器或设备创建某种polyfil或特殊情况逻辑,但也许你确实需要创建一个特殊存储算法的话,IndexedDB(IDB)可以作为您的备选。
IDB是一个非结构化数据存储,像MongoDB和其他NoSQL数据库一样。自Safari 8以来苹果就已经支持了IDB,好消息是iOS Safari IndexedDB限制高达500MB。
如果可用磁盘空间大小超过1 GB,则默认限制为500 MB;否则它是可用磁盘空间的一半。
这是个好消息,如果需要,你至少有一个备选的存储方案,通过IDB来使Service Worker保存更多的数据。
目前web平台最新的特性是Storage API,仅有Chrome和Opera支持,其他厂商应该会很快跟进。
因为这是一项新功能,所以只有在检查支持性后才能调用storage.estimate
。这可以通过验证 navigator 是否存在 storage 对象(术语是StorageManager)来完成,之后还要验证 estimate 方法是否属于 StorageManager。
if ('storage' in navigator && 'estimate' in navigator.storage) {
navigator.storage.estimate()
.then(function(estimate){
console.log(`Using ${estimate.usage} out of ${estimate.quota} bytes.`);
});
}
estimate 方法返回一个解析 StorageEstimate 对象的 Promise 实例,then中返回的参数包含两个属性 -- usage 和 quota。两者都是与该值相关联的存储属性的保守近似值,usage 属性是对缓存量的近似值,quota 属性是可用于存储的空间的近似值。
这些值以bytes
为单位,这意味着要转换为M
,您应该除以1000000
(如果使用使用1024作为千字节标准应该是1048576
)。
正如你所见,我已经使用了磁盘空余的33GB里的18MB(缓存的主要是图片)。强调下,这里的30+GB并没有独立出来,大部分都是手机上未使用的空间。
如果我使用的存储被限制为35MB,那么我必需有一种清除缓存中的文件的机制。 Fast Furniture演示站点可以代表一种常见的电子商务站点,其中包含大量产品图像,占比达90%以上。
在我即将推出的PWA课程中,我将详细介绍如何创建缓存管理系统。 Fast Furniture站点使用多种缓存,其中不同的规则应用于不同的资源类型。图片具有自己的缓存以及在缓存时间及数量上的限制。
你可以依据平均资源大小来扩展逻辑并调整规则来使其更加完善。比如说,Fast Furniture中使用响应式图像,这意味着我可能能够存储更多的图片。当然,这最终取决于可用的空间大小。
如果这听起来很复杂,我总是说从简单中成长,所以不要担心,它不一定很复杂。
在规划阶段,了解你的应用能够使用多少存储非常重要。你需要在缓存所有内容和选择性缓存之间找到一个很好的平衡点。
浏览器就构成适当的存储容量规则达成了普遍的共识。与开发领域的所有内容一样,主要取决于消费者的设备。
由于大多数访问者都是移动端访问,因此你应该规划大约50MB的可用空间,这应该使你能够在不消耗用户带宽的情况下来创建良好体验。
随着可用空间的增加,你还可以增加规划缓存的大小。