7、數(shù)據(jù)存儲(chǔ)
在開(kāi)發(fā)Web應(yīng)用的過(guò)程中,會(huì)涉及一些數(shù)據(jù)的存儲(chǔ)需求,常見(jiàn)的存儲(chǔ)方式可能有:
保存登錄態(tài)的Cookie;
使用瀏覽器本地存儲(chǔ)進(jìn)行保存的Local Storage和Session Storage;
客戶端數(shù)據(jù)持久化存儲(chǔ)方案涉及的Web SQL和IndexedDB;
直接存儲(chǔ)在本機(jī)的文件系統(tǒng)上等。
文件系統(tǒng)、WebSQL和IndexedDB都是異步方式,
而本地存儲(chǔ)的Local Storage和Session Storage方式則是同步方式。
Cache Storage是一種為緩存網(wǎng)絡(luò)請(qǐng)求與響應(yīng)而設(shè)計(jì)的數(shù)據(jù)存儲(chǔ)機(jī)制,這些請(qǐng)求與響應(yīng)可以是在應(yīng)用程序運(yùn)行過(guò)程中常規(guī)創(chuàng)建的,也可以是專門為了在緩存中存儲(chǔ)一些數(shù)據(jù)而創(chuàng)建的。
IndexedDB 的實(shí)踐
當(dāng)瀏覽的網(wǎng)站頁(yè)面被加載出來(lái)時(shí),首先需要向服務(wù)器請(qǐng)求相應(yīng)數(shù)據(jù)來(lái)構(gòu)造頁(yè)面顯示的狀態(tài)信息,然后再利用這些信息完成頁(yè)面渲染,如果能將首次請(qǐng)求的信息保存到IndexedDB中,則能有效減少一些頻繁訪問(wèn)頁(yè)面的加載時(shí)間。
1、注意平臺(tái)兼容性:使用 ArrayBuffer 存儲(chǔ)(更兼容)
Blob類型比ArrayBuffer類型多了一個(gè)MIME類型的字段,為了能夠正確地進(jìn)行數(shù)據(jù)類型轉(zhuǎn)化,將ArrayBuffer類型轉(zhuǎn)化為Blob類型時(shí)需將該類型字段也加入緩沖區(qū)。代碼示例如下:
將Blob類型轉(zhuǎn)化為ArrayBuffer類型的過(guò)程會(huì)稍復(fù)雜一些,需要通過(guò)異步方式使用FileReader對(duì)象以ArrayBuffer格式讀取Blob對(duì)象,然后在讀取完成所觸發(fā)的loadend事件中處理轉(zhuǎn)化結(jié)果。代碼示例如下:
2、完善錯(cuò)誤處理
在進(jìn)行數(shù)據(jù)存儲(chǔ)時(shí),會(huì)因?yàn)楹芏嘣蛟斐蓴?shù)據(jù)的讀寫(xiě)失敗,并且數(shù)據(jù)存儲(chǔ)在某些情況下是不可控的。
由于IndexedDB的主要操作方法都集中在IDBDatabase、IDBTransaction和IDBRequest接口對(duì)象上,所以可為它們添加error監(jiān)聽(tīng)事件,然后根據(jù)報(bào)錯(cuò)信息進(jìn)行恰當(dāng)?shù)腻e(cuò)誤處理。以監(jiān)聽(tīng)打開(kāi)或創(chuàng)建IndexedDB的操作情況為例,代碼如下:
3、注意修改、刪除和過(guò)期
針對(duì)歷史版本進(jìn)行相應(yīng)的升級(jí)處理,可以使用IDBOpenDBRequest.onupgradeneeded()方法來(lái)捕獲IndexedDB版本升級(jí)事件,具體代碼示例如下:
4、存儲(chǔ)性能
雖然操作IndexedDB的API均是異步執(zhí)行的,但不正確的使用方式依然會(huì)帶來(lái)存儲(chǔ)的性能風(fēng)險(xiǎn),可能阻塞主線程造成應(yīng)用崩潰或無(wú)響應(yīng)。
產(chǎn)生風(fēng)險(xiǎn)的主要原因是IndexedDB在存儲(chǔ)數(shù)據(jù)對(duì)象時(shí),需要首先創(chuàng)建該數(shù)據(jù)對(duì)象的一個(gè)結(jié)構(gòu)化副本,而這個(gè)復(fù)制過(guò)程是在主線程中進(jìn)行的,所以數(shù)據(jù)對(duì)象嵌套的越復(fù)雜、規(guī)模越大,對(duì)主線程的阻塞時(shí)間就會(huì)越長(zhǎng)。因此在操作IndexedDB時(shí)可參考這條規(guī)則:讀寫(xiě)數(shù)據(jù)的大小不應(yīng)該大于待訪問(wèn)的數(shù)據(jù)大小。
對(duì)規(guī)模較大的狀態(tài)數(shù)據(jù)進(jìn)行頻繁改動(dòng)時(shí),也會(huì)給主線程的執(zhí)行帶來(lái)很大壓力,即便采用了防抖和節(jié)流,也可能阻塞主線程的執(zhí)行,增加數(shù)據(jù)寫(xiě)入出錯(cuò)的風(fēng)險(xiǎn)。**因此可采取的優(yōu)化方式是:將原本整個(gè)狀態(tài)對(duì)象的存儲(chǔ)方式分解為粒度更小的單個(gè)狀態(tài)記錄進(jìn)行存儲(chǔ)。**這樣可在進(jìn)行狀態(tài)更新時(shí),僅更新實(shí)際發(fā)生修改的狀態(tài)記錄,而不會(huì)引起整個(gè)應(yīng)用的狀態(tài)對(duì)象進(jìn)行大規(guī)模的數(shù)據(jù)存儲(chǔ)。
8、緩存技術(shù)
緩存的原理是在首次請(qǐng)求后保存一份請(qǐng)求資源的響應(yīng)副本,當(dāng)用戶再次發(fā)起相同請(qǐng)求后,如果判斷緩存命中則攔截請(qǐng)求,將之前存儲(chǔ)的響應(yīng)副本返回給用戶,從而避免重新向服務(wù)器發(fā)起資源請(qǐng)求。
緩存的技術(shù)種類有很多,比如代理緩存、瀏覽器緩存、網(wǎng)關(guān)緩存、負(fù)載均衡器及內(nèi)容分發(fā)網(wǎng)絡(luò)等,
它們大致可以分為兩類:共享緩存和私有緩存。
共享緩存指的是緩存內(nèi)容可被多個(gè)用戶使用,如公司內(nèi)部架設(shè)的Web代理;
私有緩存指的是只能單獨(dú)被用戶使用的緩存,如瀏覽器緩存。
HTTP緩存應(yīng)該算是前端開(kāi)發(fā)中最常接觸的緩存機(jī)制之一,它又可細(xì)分為強(qiáng)制緩存與協(xié)商緩存,二者最大的區(qū)別在于判斷緩存命中時(shí),瀏覽器是否需要向服務(wù)器端進(jìn)行詢問(wèn)以協(xié)商緩存的相關(guān)信息,進(jìn)而判斷是否需要就響應(yīng)內(nèi)容進(jìn)行重新請(qǐng)求。
1、Service Worker
Service Worker是瀏覽器后臺(tái)獨(dú)立于主線程之外的工作線程,正因如此它的處理能力能夠脫離瀏覽器窗體而不影響頁(yè)面的渲染性能。
Service Worker是伴隨著Google推出的PWA(即Progressive Web App漸進(jìn)式Web應(yīng)用)一同出現(xiàn)的技術(shù),它能夠?qū)崿F(xiàn)諸如消息推送、后臺(tái)加載、離線應(yīng)用及移動(dòng)端添加到主屏等堪比原生應(yīng)用的功能,同時(shí)還具備小程序“無(wú)須安裝、用完即走”的體驗(yàn)特點(diǎn)。雖然Service Worker已被列入W3C標(biāo)準(zhǔn),但在各端上的兼容性并不理想,目前來(lái)講應(yīng)用比較多的還是在基于Chrome的PC端瀏覽器上。(最新的兼容性可以查看相應(yīng)網(wǎng)站)
1、技術(shù)由來(lái)
JavaScript的執(zhí)行是單線程的,如果一個(gè)任務(wù)的執(zhí)行占用并消耗了許多計(jì)算資源,則勢(shì)必會(huì)導(dǎo)致阻塞執(zhí)行其他任務(wù),這正是單線程的弊端。
為此瀏覽器引入了Web Worker,它是一個(gè)獨(dú)立于瀏覽器主線程之外的工作線程,可以將較復(fù)雜的運(yùn)算交給它來(lái)處理,而無(wú)須擔(dān)心這是否會(huì)對(duì)頁(yè)面渲染產(chǎn)生負(fù)面影響。
Service Worker正是在此基礎(chǔ)上增加了對(duì)離線緩存的管理能力,它的表現(xiàn)彌補(bǔ)了之前HTML 5上采用AppCache實(shí)現(xiàn)離線緩存的諸多缺陷。
Service Worker定義了由事件驅(qū)動(dòng)的生命周期,這使得頁(yè)面上任何網(wǎng)絡(luò)請(qǐng)求事件都可以被其攔截并加以處理,同時(shí)還能訪問(wèn)緩存和IndexedDB,這就可以讓開(kāi)發(fā)者制定自定義度更高的緩存管理策略,從而提高離線弱網(wǎng)環(huán)境下的Web運(yùn)行體驗(yàn)。
2、基本特征
●獨(dú)立于瀏覽器主線程,無(wú)法直接操作DOM。
●在開(kāi)發(fā)過(guò)程中可以通過(guò)localhost使用,但要部署到線上環(huán)境則需要HTTPS的支持。
●能夠監(jiān)聽(tīng)并攔截全站的網(wǎng)絡(luò)請(qǐng)求,從而進(jìn)行自定義請(qǐng)求響應(yīng)控制。
●在不使用的時(shí)候會(huì)被中止,在需要的時(shí)候進(jìn)行重啟。所以我們不能依賴在其onmessage與onfetch的事件監(jiān)聽(tīng)處理程序中的全局狀態(tài),如果有此需要可以通過(guò)訪問(wèn)IndexedDB API將全局狀態(tài)進(jìn)行存儲(chǔ)。
●廣泛使用Promise來(lái)處理異步。
●消息推送。
●后臺(tái)同步。
2、Push 緩存
HTTP 2新增了一個(gè)強(qiáng)大的功能:服務(wù)器端推送,它的出現(xiàn)打破了傳統(tǒng)意義上的請(qǐng)求與響應(yīng)一對(duì)一的模式,服務(wù)器可以對(duì)客戶端瀏覽器的一個(gè)請(qǐng)求發(fā)送多個(gè)響應(yīng)。
這樣會(huì)帶來(lái)性能優(yōu)化的一個(gè)新思路:在傳統(tǒng)的網(wǎng)絡(luò)應(yīng)用中,客戶端若想將應(yīng)用中所包含的多種資源渲染展示在瀏覽器中,就需要逐個(gè)資源進(jìn)行請(qǐng)求,但其實(shí)一個(gè)HTML文件中所包含的JavaScript、樣式表及圖片等文件資源,是服務(wù)器可以在收到該HTML請(qǐng)求后預(yù)判出稍后會(huì)到來(lái)的請(qǐng)求,那么就可以利用服務(wù)器端推送節(jié)省這些多余的資源請(qǐng)求,來(lái)提升頁(yè)面加載的速度。
1、最后一道緩存
瀏覽器緩存通??梢苑譃樗膫€(gè)方面:內(nèi)存中的緩存、Service Worker緩存、HTTP緩存及HTTP 2的Push緩存。
1、內(nèi)存中的緩存
內(nèi)存中的緩存是瀏覽器中響應(yīng)速度最快且命中優(yōu)先級(jí)最高的一種緩存,但它的駐留周期非常短,通常依賴于渲染進(jìn)程,一旦頁(yè)面頁(yè)簽關(guān)閉進(jìn)程結(jié)束,內(nèi)存中的緩存數(shù)據(jù)就會(huì)被回收。
2、緩存命中優(yōu)先級(jí)
瀏覽器緩存的命中優(yōu)先級(jí)從高到低分別是:內(nèi)存中的緩存、Service Worker緩存、HTTP緩存及HTTP 2的Push緩存。
3、基于連接的緩存
在了解了緩存命中優(yōu)先級(jí)后,我們還需要明白Push緩存是依賴于HTTP 2連接的,如果連接斷開(kāi),即便推送的資源具有較高的可緩存性,它們也會(huì)丟失,這就意味著需要建立新的連接并重新下載資源??紤]到網(wǎng)絡(luò)可能存在不穩(wěn)定性,建議不要長(zhǎng)時(shí)間依賴Push緩存中的資源內(nèi)容,它更擅長(zhǎng)的是資源推送到頁(yè)面提取間隔時(shí)長(zhǎng)較短的使用場(chǎng)景。
4、預(yù)加載 與 Push 緩存
Push緩存和預(yù)加載還存在一些不同之處,其中主要的不同點(diǎn)是,Push緩存是由服務(wù)器端決定何時(shí)向客戶端預(yù)先推送資源的,而預(yù)加載則是當(dāng)客戶端瀏覽器收到HTML文件后,經(jīng)過(guò)解析其中帶有preload的標(biāo)簽,才會(huì)開(kāi)啟預(yù)加載的。
為了方便決定使用Push緩存還是預(yù)加載,下面給出一個(gè)決策樹(shù)以供參考:
3、CDN 緩存
CDN全稱Content Delivery Network,即內(nèi)容分發(fā)網(wǎng)絡(luò),它是構(gòu)建在現(xiàn)有網(wǎng)絡(luò)基礎(chǔ)上的虛擬智能網(wǎng)絡(luò),依靠部署在各地的邊緣服務(wù)器,通過(guò)中心平臺(tái)的負(fù)載均衡、調(diào)度及內(nèi)容分發(fā)等功能模塊,使用戶在請(qǐng)求所需訪問(wèn)的內(nèi)容時(shí)能夠就近獲取,以此來(lái)降低網(wǎng)絡(luò)擁塞,提高資源對(duì)用戶的響應(yīng)速度。
與前端關(guān)系密切的CDN優(yōu)化點(diǎn):域名設(shè)置。
Cookie的訪問(wèn)遵循同源策略,并且同一域名下的所有請(qǐng)求都會(huì)攜帶全部Cookie信息。若這些完全沒(méi)有必要的開(kāi)銷積少成多,那么它們所產(chǎn)生的流量浪費(fèi)就會(huì)很大,所以將CDN服務(wù)器的域名和主站域名進(jìn)行區(qū)分是非常有價(jià)值的實(shí)踐。
因?yàn)闉g覽器對(duì)于同域名下的并發(fā)請(qǐng)求存在限制,通常Chrome的并發(fā)限制數(shù)是6,其他瀏覽器可能多少會(huì)有所差異。這種限制也同時(shí)為我們提供了一種解決方案:通過(guò)增加類似域名的方式來(lái)提高并發(fā)請(qǐng)求數(shù),比如對(duì)多個(gè)圖片文件進(jìn)行并發(fā)請(qǐng)求的場(chǎng)景,可以通過(guò)擴(kuò)展如下類似域名的方式來(lái)規(guī)避限制:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-848716.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-848716.html
到了這里,關(guān)于Web 前端性能優(yōu)化之七:數(shù)據(jù)存儲(chǔ)與緩存技術(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!