您当前的位置:首页 > 电脑百科 > 程序开发 > 前端

聊聊前端存储库Localforage和存储配额

时间:2023-02-03 12:12:37  来源:  作者:大转转FE

前言

浏览器本地存储,是每一个前端小伙伴都相当熟悉的知识点。

目前使用率最高的当之无愧为Web Storage API​,也就是localStorage和sessionStorage​,API简单,读取效率高。然后是indexedDB​,但大部分时间是存在于八股文和面试题中。indexedDB​的优势为存储空间大,且支持各种数据结构,性能也没有问题。之所以不为重用,是因为indexedDB​的API多、长且纷杂。另外,前端使用数据库还需要了解一些表、游标、事务等一些概念,对于不了解后端的同学来说上手成本也就高出localStorage​太多。所以,在5M内的存储领域,indexedDB​并非首选。另外WebSQL​已被H5标准放弃,而元老级的Cookie也不再适合现代的客户端存储任务。

那么有没有一个既保留indexedDB​优点,上手又简单的方法呢,答案就是封装js库,localforage就是一个比较成熟的方案。

localforage

简介

localforage是一个 JAVAScript 库,通过简单类似 localStorage API 的异步存储来改进你的 Web 应用程序的离线体验。它能存储多种类型的数据,而不仅仅是字符串。

localforage​采用优雅降级策略,若浏览器不支持indexedDB​ 或 WebSQL​,则使用 localStorage​。所以,在优先选用indexedDB存储的前提下,兼容性也得以保证,在所有主流浏览器中都可使用:Chrome,Firefox,IE 和 Safari(包括 Safari Mobile)。

localforage在Github上拥有21.5k个star,npm下载量每周200w左右,正常使用也不会出现问题。

用法

详细的使用方法不做过多赘述,只讲一下存取示例。

  • setItem

 

// 通过 localForage 完成存储
localforage.setItem('key', 'value').then(doSomethingElse); 

// localForage 同样支持回调函数 
localforage.setItem('key', 'value', doSomethingElse);
 
  • getItem

 

 
localforage.getItem('somekey').then(function(value) { 
    // 当离线仓库中的值被载入时,此处代码运行 
    console.log(value); 
}).catch(function(err) { 
    // 当出错时,此处代码运行 
    console.log(err); 
}); 
// 回调版本: 
localforage.getItem('somekey', function(err, value) { 
    // 当离线仓库中的值被载入时,此处代码运行 
    console.log(value); 
});

实践

在一次的业务需求中,基于以下两点,果断选择了localforage。

  1. 后期会有大量数据需要本地存储。
  2. 转转内部有基于localforage.js二次封装的库,且包含设置过期时间的方法,适用于此次需求。

上线后的一段时间,该功能平稳运行。直到sentry(错误日志监控系统)出现了大量关于内存溢出的报错......

问题处理

艰难复现

起初怀疑是localforage​有兼容性问题,但是localforage​有优雅降级机制。再加上报错内容为QuotaExceededError​,所以在阅读大量资料后基本锁定为在indexedDB的使用上出现了问题。另外,报错用户数量为个位数,说明了是用户操作或手机存在异常导致的问题。

在确定了问题的大体方向,排查代码没有思路的前提下,眼前能做的就是复现这个问题。

刚才提到,QuotaExceededError为内存溢出类型报错,直觉告诉我,需要找一个内存空间剩余最少的测试机,但当时最少的也剩余20GB,于是下载了一天大型软件后,终于在内存剩余100MB左右时成功复现。

问题原因

不同于浏览器会为localStorage​预留5MB左右的储存空间,indexedDB的配额是动态计算的,准确的说是浏览器的储存配额是动态计算的,虽然浏览器实现各不相同,但可用存储量通常取决于设备上可用的存储量。

这个可用的存储量称为全局限制,Firefox大约为可用磁盘空间的50%,Chrome的这一数据能达到80%。如果超过此范围,则会发起称为源回收的过程,删除整个源的数据,直到存储量再次低于限制。删除源数据没有只删一部分的说法——因为这样可能会导致不一致的问题。

除全局限制外,还有另一个限制称为组限制——为全局限制的20%。这里可以把每个二级域名看作一组,每组可以聚合使用最多20%的全局限制。

如果超出组限制,或者源回收过程无法释放足够空间,indexedDB​ 或缓存 API就会抛出名为 QuotaExceededError​ 的 DOMError。

如何查看有多少可用存储空间?

 

if (navigator.storage && navigator.storage.estimate) { 
    const quota = await navigator.storage.estimate(); 
    // quota.usage -> 已使用的字节数。
    // quota.quota -> 可用最大字节数。
    const percentageUsed = (quota.usage / quota.quota) * 100; 
    console.log(`已使用${percentageUsed}%可用储存。`); 
    const remaining = quota.quota - quota.usage; 
    console.log(`最多可再写入${remaining}字节。`); 
}

Ps.这个方法使用了StorageManager API,使用前要先对其进行功能检测。实测过程中,Android的webview支持此方法,IOS却不支持。

如何解决

优雅降级只是去判断了浏览器是否支持某种本地存储的方法,但无法处理硬盘不足的问题,所以如果想去避免这个问题,可以在业务代码中使用try...catch进行异常捕获,手动进行异常处理。

业务中常用的解决办法是弹窗提示用户去清理手机硬盘。实测中,华为手机硬盘小于100MB时,系统层也会弹出清理手机的弹窗提示。

 

try {
    localforage.setItem('key', 'value', doSomethingElse);
} catch(err) {
    if (err.name === 'QuotaExceededError') {
        //异常处理
    }
}

总结&思考

  • localforage​是个优秀的前端存储js库,某种角度来讲,indexedDB​的发展要感谢localforage。
  • 不论localStorage​还是indexedDB​,存储空间都受浏览器存储配额的影响,而浏览器的存储配额取决于本地磁盘剩余空间的大小。配额不足就会导致浏览器报QuotaExceededError。
  • 开源轮子查问题没思路时,在代码仓库issue中查找会是一个捷径,作者就忽略了这点绕了弯路。

参考资料

1.https://web.dev/storage-for-the-web/

2.https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria

3.https://www.zhangxinxu.com/wordPress/ target=_blank class=infotextkey>WordPress/2018/06/js-localforage-localstorage-indexdb/



Tags:Localforage   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
聊聊前端存储库Localforage和存储配额
前言浏览器本地存储,是每一个前端小伙伴都相当熟悉的知识点。目前使用率最高的当之无愧为Web Storage API​,也就是localStorage和sessionStorage​,API简单,读取效率高。然后是...【详细内容】
2023-02-03  Search: Localforage  点击:(220)  评论:(0)  加入收藏
▌简易百科推荐
20k级别前端是怎么使用LocalStorage的,想知道吗?
当咱们把咱们想缓存的东西,存在localStorage、sessionStorage中,在开发过程中,确实有利于咱们的开发,咱们想看的时候也是一目了然,点击Application就可以看到。前言大家好,我是林...【详细内容】
2024-03-26  前端之神  微信公众号  Tags:前端   点击:(13)  评论:(0)  加入收藏
前端不存在了?盲测64%的人更喜欢GPT-4V的设计,杨笛一等团队新作
3 月 9 日央视的一档节目上,百度创始人、董事长兼 CEO 李彦宏指出,以后不会存在「程序员」这种职业了,因为只要会说话,人人都会具备程序员的能力。「未来的编程语言只会剩下两种...【详细内容】
2024-03-11  机器之心Pro    Tags:前端   点击:(16)  评论:(0)  加入收藏
前端开始“锈化”?Vue团队开源JS打包工具:基于Rust、速度极快、尤雨溪主导
Vue 团队已正式开源Rolldown —— 基于 Rust 的 JavaScrip 打包工具。Rolldown 是使用 Rust 开发的 Rollup 替代品,它提供与 Rollup 兼容的应用程序接口和插件接口...【详细内容】
2024-03-09  OSC开源社区    Tags:Vue   点击:(20)  评论:(0)  加入收藏
两年前端经验还不会手写Promise?
什么是promise?当我们处理异步操作时,我们经常需要进行一系列的操作,如请求数据、处理数据、渲染UI等。在过去,这些操作通常通过回调函数来处理,但是回调函数嵌套过多会导致代码...【详细内容】
2024-03-07  海燕技术栈  微信公众号  Tags:Promise   点击:(27)  评论:(0)  加入收藏
网站开发中的前端和后端开发有什么区别
前端开发和后端开发都是干什么的?有哪些区别?通俗地讲,前端干的工作是用户可以直接看得见的,而后端开发的工作主要在服务端,用户不太能直接看到。虽然前端开发和后端开发的工作有...【详细内容】
2024-02-21  CarryData    Tags:前端   点击:(35)  评论:(0)  加入收藏
网站程序开发中的前后端分离技术
随着互联网的快速发展和技术的不断创新,传统的网站开发模式已经难以满足日益增长的业务需求。为了提高开发效率、增强系统的可维护性和可扩展性,前后端分离技术逐渐成为了网站...【详细内容】
2024-01-31  网站建设派迪星航    Tags:前后端分离   点击:(26)  评论:(0)  加入收藏
如何优雅的实现前端国际化?
JavaScript 中每个常见问题都有许多成熟的解决方案。当然,国际化 (i18n) 也不例外,有很多成熟的 JavaScript i18n 库可供选择,下面就来分享一些热门的前端国际化库!i18nexti18ne...【详细内容】
2024-01-17  前端充电宝  微信公众号  Tags:前端   点击:(74)  评论:(0)  加入收藏
Vue中Scope是怎么做样式隔离的?
scope样式隔离在 Vue 中,样式隔离是通过 scoped 特性实现的。当在一个组件的 <style> 标签上添加 scoped 特性时,Vue 会自动为这个样式块中的所有选择器添加一个唯一的属性,以...【详细内容】
2024-01-04  海燕技术栈  微信公众号  Tags:Vue   点击:(83)  评论:(0)  加入收藏
vue3中 ref和 reactive的区别 ?
最近有朋友在面试过程中经常被问到这么一个问题,vue3 中的ref 和 reactive的区别在哪里,为什么 要定义两个API 一个 api不能实现 响应式更新吗??带着这个疑问 ,我们 接下来进行逐...【详细内容】
2024-01-03  互联网高级架构师  今日头条  Tags:vue3   点击:(42)  评论:(0)  加入收藏
React18 与 Vue3 全方面对比
1. 编程风格 & 视图风格1.1 编程风格 React 语法少、难度大;Vue 语法多,难度小例如指令:Vue<input v-model="username"/><ul> <li v-for="(item,index) in list" :key="inde...【详细内容】
2024-01-03  爱做梦的程序员  今日头条  Tags:Vue3   点击:(74)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条