日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
聊聊前端存儲(chǔ)庫(kù)Localforage和存儲(chǔ)配額

前言

瀏覽器本地存儲(chǔ),是每一個(gè)前端小伙伴都相當(dāng)熟悉的知識(shí)點(diǎn)。

目前使用率最高的當(dāng)之無(wú)愧為Web Storage API?,也就是localStorage和sessionStorage?,API簡(jiǎn)單,讀取效率高。然后是indexedDB?,但大部分時(shí)間是存在于八股文和面試題中。indexedDB?的優(yōu)勢(shì)為存儲(chǔ)空間大,且支持各種數(shù)據(jù)結(jié)構(gòu),性能也沒(méi)有問(wèn)題。之所以不為重用,是因?yàn)閕ndexedDB?的API多、長(zhǎng)且紛雜。另外,前端使用數(shù)據(jù)庫(kù)還需要了解一些表、游標(biāo)、事務(wù)等一些概念,對(duì)于不了解后端的同學(xué)來(lái)說(shuō)上手成本也就高出localStorage?太多。所以,在5M內(nèi)的存儲(chǔ)領(lǐng)域,indexedDB?并非選擇。另外WebSQL?已被H5標(biāo)準(zhǔn)放棄,而元老級(jí)的Cookie也不再適合現(xiàn)代的客戶(hù)端存儲(chǔ)任務(wù)。

那么有沒(méi)有一個(gè)既保留indexedDB?優(yōu)點(diǎn),上手又簡(jiǎn)單的方法呢,答案就是封裝js庫(kù),localforage就是一個(gè)比較成熟的方案。

localforage

簡(jiǎn)介

localforage是一個(gè) JavaScript 庫(kù),通過(guò)簡(jiǎn)單類(lèi)似 localStorage API 的異步存儲(chǔ)來(lái)改進(jìn)你的 Web 應(yīng)用程序的離線體驗(yàn)。它能存儲(chǔ)多種類(lèi)型的數(shù)據(jù),而不僅僅是字符串。

localforage?采用優(yōu)雅降級(jí)策略,若瀏覽器不支持indexedDB? 或 WebSQL?,則使用 localStorage?。所以,在優(yōu)先選用indexedDB存儲(chǔ)的前提下,兼容性也得以保證,在所有主流瀏覽器中都可使用:Chrome,F(xiàn)irefox,IE 和 Safari(包括 Safari Mobile)。

localforage在github上擁有21.5k個(gè)star,npm下載量每周200w左右,正常使用也不會(huì)出現(xiàn)問(wèn)題。

用法

詳細(xì)的使用方法不做過(guò)多贅述,只講一下存取示例。

  • setItem
// 通過(guò) localForage 完成存儲(chǔ)
localforage.setItem('key', 'value').then(doSomethingElse);

// localForage 同樣支持回調(diào)函數(shù)
localforage.setItem('key', 'value', doSomethingElse);

  • getItem
localforage.getItem('somekey').then(function(value) { 
// 當(dāng)離線倉(cāng)庫(kù)中的值被載入時(shí),此處代碼運(yùn)行
console.log(value);
}).catch(function(err) {
// 當(dāng)出錯(cuò)時(shí),此處代碼運(yùn)行
console.log(err);
});
// 回調(diào)版本:
localforage.getItem('somekey', function(err, value) {
// 當(dāng)離線倉(cāng)庫(kù)中的值被載入時(shí),此處代碼運(yùn)行
console.log(value);
});

實(shí)踐

在一次的業(yè)務(wù)需求中,基于以下兩點(diǎn),果斷選擇了localforage。

  1. 后期會(huì)有大量數(shù)據(jù)需要本地存儲(chǔ)。
  2. 轉(zhuǎn)轉(zhuǎn)內(nèi)部有基于localforage.js二次封裝的庫(kù),且包含設(shè)置過(guò)期時(shí)間的方法,適用于此次需求。

上線后的一段時(shí)間,該功能平穩(wěn)運(yùn)行。直到sentry(錯(cuò)誤日志監(jiān)控系統(tǒng))出現(xiàn)了大量關(guān)于內(nèi)存溢出的報(bào)錯(cuò)......

問(wèn)題處理

艱難復(fù)現(xiàn)

起初懷疑是localforage?有兼容性問(wèn)題,但是localforage?有優(yōu)雅降級(jí)機(jī)制。再加上報(bào)錯(cuò)內(nèi)容為QuotaExceededError?,所以在閱讀大量資料后基本鎖定為在indexedDB的使用上出現(xiàn)了問(wèn)題。另外,報(bào)錯(cuò)用戶(hù)數(shù)量為個(gè)位數(shù),說(shuō)明了是用戶(hù)操作或手機(jī)存在異常導(dǎo)致的問(wèn)題。

在確定了問(wèn)題的大體方向,排查代碼沒(méi)有思路的前提下,眼前能做的就是復(fù)現(xiàn)這個(gè)問(wèn)題。

剛才提到,QuotaExceededError為內(nèi)存溢出類(lèi)型報(bào)錯(cuò),直覺(jué)告訴我,需要找一個(gè)內(nèi)存空間剩余最少的測(cè)試機(jī),但當(dāng)時(shí)最少的也剩余20GB,于是下載了一天大型軟件后,終于在內(nèi)存剩余100MB左右時(shí)成功復(fù)現(xiàn)。

問(wèn)題原因

不同于瀏覽器會(huì)為localStorage?預(yù)留5MB左右的儲(chǔ)存空間,indexedDB的配額是動(dòng)態(tài)計(jì)算的,準(zhǔn)確的說(shuō)是瀏覽器的儲(chǔ)存配額是動(dòng)態(tài)計(jì)算的,雖然瀏覽器實(shí)現(xiàn)各不相同,但可用存儲(chǔ)量通常取決于設(shè)備上可用的存儲(chǔ)量。

這個(gè)可用的存儲(chǔ)量稱(chēng)為全局限制,F(xiàn)irefox大約為可用磁盤(pán)空間的50%,Chrome的這一數(shù)據(jù)能達(dá)到80%。如果超過(guò)此范圍,則會(huì)發(fā)起稱(chēng)為源回收的過(guò)程,刪除整個(gè)源的數(shù)據(jù),直到存儲(chǔ)量再次低于限制。刪除源數(shù)據(jù)沒(méi)有只刪一部分的說(shuō)法——因?yàn)檫@樣可能會(huì)導(dǎo)致不一致的問(wèn)題。

除全局限制外,還有另一個(gè)限制稱(chēng)為組限制——為全局限制的20%。這里可以把每個(gè)二級(jí)域名看作一組,每組可以聚合使用最多20%的全局限制。

如果超出組限制,或者源回收過(guò)程無(wú)法釋放足夠空間,indexedDB? 或緩存 API就會(huì)拋出名為 QuotaExceededError? 的 DOMError。

如何查看有多少可用存儲(chǔ)空間?

if (navigator.storage && navigator.storage.estimate) { 
const quota = await navigator.storage.estimate();
// quota.usage -> 已使用的字節(jié)數(shù)。
// quota.quota -> 可用最大字節(jié)數(shù)。
const percentageUsed = (quota.usage / quota.quota) * 100;
console.log(`已使用${percentageUsed}%可用儲(chǔ)存。`);
const remaining = quota.quota - quota.usage;
console.log(`最多可再寫(xiě)入${remaining}字節(jié)。`);
}

Ps.這個(gè)方法使用了StorageManager API,使用前要先對(duì)其進(jìn)行功能檢測(cè)。實(shí)測(cè)過(guò)程中,Android的webview支持此方法,ios卻不支持。

如何解決

優(yōu)雅降級(jí)只是去判斷了瀏覽器是否支持某種本地存儲(chǔ)的方法,但無(wú)法處理硬盤(pán)不足的問(wèn)題,所以如果想去避免這個(gè)問(wèn)題,可以在業(yè)務(wù)代碼中使用try...catch進(jìn)行異常捕獲,手動(dòng)進(jìn)行異常處理。

業(yè)務(wù)中常用的解決辦法是彈窗提示用戶(hù)去清理手機(jī)硬盤(pán)。實(shí)測(cè)中,華為手機(jī)硬盤(pán)小于100MB時(shí),系統(tǒng)層也會(huì)彈出清理手機(jī)的彈窗提示。

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

總結(jié)&思考

  • localforage?是個(gè)優(yōu)秀的前端存儲(chǔ)js庫(kù),某種角度來(lái)講,indexedDB?的發(fā)展要感謝localforage。
  • 不論localStorage?還是indexedDB?,存儲(chǔ)空間都受瀏覽器存儲(chǔ)配額的影響,而瀏覽器的存儲(chǔ)配額取決于本地磁盤(pán)剩余空間的大小。配額不足就會(huì)導(dǎo)致瀏覽器報(bào)QuotaExceededError。
  • 開(kāi)源輪子查問(wèn)題沒(méi)思路時(shí),在代碼倉(cāng)庫(kù)issue中查找會(huì)是一個(gè)捷徑,作者就忽略了這點(diǎn)繞了彎路。

參考資料

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/2018/06/js-localforage-localstorage-indexdb/


新聞名稱(chēng):聊聊前端存儲(chǔ)庫(kù)Localforage和存儲(chǔ)配額
網(wǎng)頁(yè)地址:http://m.5511xx.com/article/dhjdopp.html