摘要:如下圖所示一重繪與回流前端性能優(yōu)化最關(guān)鍵的就是減少頁面的重繪與回流。很明顯就是少了一步,這是因?yàn)榘褧?huì)觸發(fā)回流的屬性用替代,這樣就使渲染的過程減少了這一步,使渲染的時(shí)間減少從而提高性能。
我們今天來說說前端圖形渲染優(yōu)化,因?yàn)槲医酉聛淼臅r(shí)間可能要開始研究webgl方面的東西,所以就在這里把之前做過的H5做一個(gè)總結(jié),現(xiàn)同步發(fā)布于GERRY_BLOG,TiMiGerry-知乎,轉(zhuǎn)載請(qǐng)保留鏈接。靜態(tài)資源-圖片
一 、圖片格式
JPEG: 首先JPEG compress的整個(gè)流程是將圖片的顏色rgba()進(jìn)行一個(gè)轉(zhuǎn)換,然后進(jìn)行重采樣區(qū)分高頻和低頻的顏色變換,從而進(jìn)行一個(gè)DTA的過程,然后對(duì)高頻的顏色變換采樣結(jié)果進(jìn)行一個(gè)壓縮,接著量化和encoding,最后得到一個(gè)JPEG的壓縮版。這個(gè)壓縮版的圖片和原始數(shù)據(jù)的圖片是有差異的,雖然壓縮的過程中丟失了一些數(shù)據(jù),但是這些差異對(duì)于人眼是無法識(shí)別的。所以在壓縮之后不影響整體的瀏覽體驗(yàn)效果,同時(shí)對(duì)于頁面來說,靜態(tài)資源圖片的容量也可以減少很多,從而提高網(wǎng)頁的加載速度。
PNG: PNG圖片的是支持透明的一種圖片格式,其實(shí)質(zhì)就是一個(gè)顏色的索引數(shù)據(jù)集合。它有著PNG8,PNG24,PNG32三種格式,即8位,24位,32位索引。PNG的文件格式內(nèi)部有一個(gè)調(diào)色板,以PNG8 為例:PNG為256色+透明功能的格式,他的調(diào)色板中有 256 種顏色,即一個(gè)像素的顏色他需要8bit的數(shù)據(jù)長度去索引,也就是說PNG8圖片的顏色只有在這256種顏色中出現(xiàn),所以PNG8的顏色就沒有那么的豐富,有弊也用利,它的文件大小也是PNG文件格式中最小的一種。
而PNG24的圖片是需要2^24色,即一個(gè)像素的顏色他需要24bit去索引,所以png24去索引一種顏色需要的數(shù)據(jù)長度是png8的3倍,同時(shí)不支持透明,png32的圖片就是在png24的基礎(chǔ)上增加了透明的功能,PNG的圖片的選取取決于圖片的色彩。若是圖片色彩不是很豐富且比較單一的情況下,可以考慮使用PNG8的圖片,如果是圖片色彩很豐富則可以選取PNG24或PNG32位的圖片以減少圖片資源的大小。PNG圖片中每種格式圖片都有一些微小的差異,實(shí)際開發(fā)中需要平衡文件大小,圖片格式,圖片質(zhì)量和圖片大小在當(dāng)前項(xiàng)目中的重要性,,才決定使用何種圖片的格式
JPEG: 圖片的壓縮率比較高,適用于作為背景圖片,頭圖的情況適用于大面積背景的情況下使用。
PNG: 格式支持透明,這種格式的圖片兼容性很好,用于一些需要進(jìn)行透明的背景或者彈出層,或者說在一下情況下需要追求體驗(yàn)質(zhì)量而使用PNG圖片來進(jìn)行整體頁面的開發(fā)。
SVG:另外一種是SVG矢量圖,這種格式最大的好處就是放大縮小不會(huì)失真和細(xì)膩度極高同時(shí)文件相對(duì)較小和是代碼內(nèi)嵌的圖片格式,能有條件的話盡可能使用這樣的圖片,當(dāng)然這個(gè)也只能用于一些簡單的部件例如說圖標(biāo),按鈕等等一寫簡單的業(yè)務(wù)場(chǎng)景。
二、圖片處理
CSS sprite:目前來講spite還是比較常用的圖片整理方法,他的好處是將大大小小的圖片合并為一張大圖,再使用圖片定位來顯示對(duì)應(yīng)的圖片,這樣可以減少頁面的請(qǐng)求,提高頁面加載速度。但也有個(gè)缺點(diǎn)就是既然是合成一張大圖,那么很多小圖片就依賴這一張圖片,如果這個(gè)圖片沒有加載出來那么整個(gè)頁面基本上就缺失了,但以現(xiàn)在的網(wǎng)絡(luò)來說,基本上也可以忽略這個(gè)問題了,現(xiàn)在基本上是4G網(wǎng)絡(luò)或者wifi不存在速度慢的情況。
Image-inline:使用BASE64格式嵌入到頁面中也是一個(gè)很好的辦法,減少htttp請(qǐng)求,但是實(shí)際的開發(fā)中一般也比較少這樣做,因?yàn)閷D片嵌入到HTML中其實(shí)到了后面也不好去維護(hù),以我的開發(fā)經(jīng)驗(yàn)來說,一般是出現(xiàn)了沒辦法的情況下才使用BASE64的圖片格式。
例如在開發(fā)項(xiàng)目中,圖片資源一般都會(huì)放在不同域的地址中,使用CANVAS生成圖片的情況下,canvas.toDataUrl(…)會(huì)污染圖片的原來的地址,從而導(dǎo)致出現(xiàn)了跨域的問題,后端也不可因?yàn)檫@張圖片多帶帶生成的時(shí)候,這個(gè)時(shí)候用BASE64就是最簡單粗暴的解決方法。把圖片嵌入html就解決了跨域的情況。
壓縮:將圖片放在一些工具上批量進(jìn)行壓縮。
一、網(wǎng)頁渲染的過程
網(wǎng)頁在加載的過程中,首先拿到的是一個(gè)HTML文本也可以說拿到的就是一串字符串,瀏覽器parse解析器要將這個(gè)字符串進(jìn)行一系列的詞法分析,將每個(gè)標(biāo)簽生成對(duì)應(yīng)的一個(gè)token或者說是每個(gè)標(biāo)簽對(duì)應(yīng)的對(duì)象,然后從上到下解析這些token,接著就會(huì)一步步從上到下生成對(duì)應(yīng)的DOM節(jié)點(diǎn)。
當(dāng)然在詞法分析的過程中,就可以解析出link script標(biāo)簽,對(duì)應(yīng)的web資源就會(huì)被請(qǐng)求加載。JavsScript會(huì)被瀏覽器內(nèi)核的V8引擎進(jìn)行執(zhí)行,而css就與html類似,他會(huì)被解析成CSSOM,然后HTML,CSSM,SCRIPT,解析完畢之后結(jié)合,生成Rander Tree 拿到的這些基本信息之后,接著進(jìn)入layout也就是布局,最后進(jìn)行渲染Paint。
二、 HTML的加載特點(diǎn)
順序加載、并發(fā)加載:
順序加載指的是前面提到過的詞法分析,即瀏覽器在解析HTML頁面的時(shí)候是從上往下的,依次執(zhí)行。
并發(fā)加載指的是像同一個(gè)域下的靜態(tài)資源是會(huì)同時(shí)的發(fā)起請(qǐng)求,就是并發(fā)請(qǐng)求,當(dāng)然有并發(fā)請(qǐng)求那服務(wù)器也有并發(fā)請(qǐng)求的上限,例如谷歌瀏覽器一次請(qǐng)求統(tǒng)一域下的資源并發(fā)數(shù)是6。 在遇到需要大量請(qǐng)求圖片的時(shí)候,我們則需要使用懶加載或者預(yù)加載來進(jìn)行操作。
CSS阻塞、JS阻塞
css盡量寫在head中,因?yàn)閏ss加載會(huì)阻塞頁面的加載,這是有好處的,這避免了頁面加載時(shí)會(huì)出現(xiàn)css沒加載完而導(dǎo)致的出現(xiàn)頁面一閃的情況,同時(shí),css的加載是會(huì)阻塞JS的執(zhí)行,但不阻塞引入JS的加載。
js盡量寫在HTML文本的底部,因?yàn)閖s的引入會(huì)阻塞頁面的渲染,也依賴于DOM節(jié)點(diǎn)。所以,應(yīng)該先讓HTML,CSS先行加載,最后加載JS,JS的加載,當(dāng)然再不影響初屏的情況下,也可以使用異步加載defer,async,來加載當(dāng)前不是馬上就需要的JS文件,defer的加載時(shí)基于DOM加載完畢之后,依次加載執(zhí)行,而async是不是依次加載,是誰先加載完就執(zhí)行誰,用這個(gè)方法需要注意JS是否依賴,JS的執(zhí)行順序也是依次執(zhí)行有著相互的依賴關(guān)系,阻塞后續(xù)的JS邏輯的執(zhí)行,所以得排好先后。
除了defer和acync還有就是直接使用動(dòng)態(tài)加載js,一般情況下,這樣的方法會(huì)在組件的情況下使用,封裝一個(gè)組件然后使用js動(dòng)態(tài)加載JS和CSS。
Lazyload用于需要加載大量圖片但可以根據(jù)用戶的操作來決定加載數(shù)量,目的是減少對(duì)服務(wù)器的請(qǐng)求和減少網(wǎng)絡(luò)流量的浪費(fèi),同時(shí)也提高了用戶的體驗(yàn)度。例如一些電商的頁面展示商品,在瀏覽器滾動(dòng)到的地方加載相應(yīng)的數(shù)據(jù),而不是一口氣把所有的數(shù)據(jù)全部列出來。在H5頁面中下拉刷新,上拉加載也是很常見的做法,當(dāng)然這里由于IOS本身的瀏覽器特性也需要做一些相應(yīng)的處理。
Preload用于一些需要注重用戶體驗(yàn)和流暢的運(yùn)行頁面交互的情況,在頁面加載的同時(shí)先把所有的數(shù)據(jù)全部加載好之后,再打開頁面。最常見的做法就是使用加載進(jìn)度條,先把所有的靜態(tài)資源先用一個(gè)數(shù)組存放好,然后依次加載計(jì)算百分比,到達(dá)100%之后在走下一步操作。
重繪與回流我們先說一個(gè)幀的概念,目前,大部分的設(shè)備屏幕的的刷新頻率是60次/秒,也就是1000/60=1.6ms為一幀畫面。 瀏覽器要做任何的渲染那么他的這個(gè)渲染時(shí)間必須小于1.6ms或者盡量接近1.6ms,否則,就會(huì)出現(xiàn)卡頓的現(xiàn)象,影響用戶體驗(yàn)。 假設(shè)現(xiàn)在瀏覽器渲染一個(gè)動(dòng)畫的時(shí)間剛好為一幀,那么,這一幀的畫面這會(huì)首先會(huì)重新計(jì)算style(css/dom等)接著回流,更新tree,再進(jìn)行重繪(painting),最后再進(jìn)行圖層合并(Composite)。如下圖所示
一、重繪與回流:
前端性能優(yōu)化最關(guān)鍵的就是減少頁面的重繪與回流。
回流(reflow)即當(dāng)前頁面的布局和幾何屬性發(fā)生改變時(shí),那么就會(huì)觸發(fā)回流的機(jī)制。
重繪( repaint)即render tree 的本身一些屬性更新了,但不影響整體的布局,只是改變了背景,顏色等等這就叫重繪。
二、優(yōu)化:
減少重繪制與回流
避免使用會(huì)觸發(fā)回流的一些屬性,有些屬性會(huì)觸發(fā)回流的機(jī)制,例如:top,height等與布局相關(guān)的屬性,舉個(gè)栗子:@keyframes animation中 位移的方法用translateX替代top,以下圖為例:很明顯就是少了一步layout,這是因?yàn)榘褧?huì)觸發(fā)回流的top屬性用translate替代,這樣就使渲染的過程減少了layout這一步,使渲染的時(shí)間減少從而提高性能。
很明顯就是少了一步layout,這是因?yàn)榘褧?huì)觸發(fā)回流的top屬性用translate替代,這樣就使渲染的過程減少了layout這一步,使渲染的時(shí)間減少從而提高性能。
獨(dú)立頻繁渲染圖層,把需要進(jìn)行頻繁回流重繪的那個(gè)區(qū)塊,拿出來作為一個(gè)多帶帶的圖層,使瀏覽器的回流重繪范圍減小,從而減少cpu的資源消耗。因?yàn)椋瑸g覽器渲染的過程是這樣的:
現(xiàn)將DOM分割成多個(gè)圖層;
然后將每個(gè)層?xùn)鸥窕⒐?jié)點(diǎn)繪制到圖中;
然后圖層作為紋理上傳到GPU;
最后進(jìn)行圖層的重組,我們只要對(duì)那個(gè)需要操作的圖層獨(dú)立進(jìn)行重繪與回流就不會(huì)影響到其他的圖層。
依照上面的渲染流程,這里就要講到一個(gè)GPU加速的概念,既然我們創(chuàng)建了一個(gè)新的合成層其實(shí)也就是開啟了GPU的加速,創(chuàng)建新的圖層方法有以下幾種:
3D或透視轉(zhuǎn)換
使用加速視頻解碼的video元素;
擁有3D(WelGL)上下文或加速器的2D上下文canvas元素;
對(duì)自己的opactiy做css運(yùn)畫或使用webkit轉(zhuǎn)換的元素;
擁有加速css過濾的元素;
元素A擁有一個(gè)z-index比自己小的元素B,且元素B是一個(gè)合成層(換句話說就是該元素在復(fù)合層上面渲染),則元素A會(huì)提升為合成層 ;
以第2點(diǎn)為例:打開英雄聯(lián)盟的比賽直播視頻:
我們可以看到,這里video為什么會(huì)成為一個(gè)圖層,這里就有一個(gè)解釋。
這里提一下第7點(diǎn),因?yàn)樵趯?shí)際的開發(fā)項(xiàng)目中,尤其是移動(dòng)端做一些動(dòng)畫效果的時(shí)候會(huì)常遇到的問題。
依照上圖的情況,元素B應(yīng)該在多帶帶的合成層上,并且屏幕的最終圖像應(yīng)該在 GPU 上組成。但是A元素在B元素的頂部,我們沒有指定A元素和B元素的層級(jí)。那么瀏覽器這個(gè)時(shí)候它將強(qiáng)制為元素A創(chuàng)建一個(gè)新的合成圖層, 這樣,A和B都被變成了多帶帶的合成層。因此,使用 GPU 加速提升動(dòng)畫性能時(shí),最好給當(dāng)前動(dòng)畫元素增加一個(gè)高一點(diǎn)的 z-index 屬性,人為干擾復(fù)合層的排序,可以有效減少 Chrome 創(chuàng)建不必要的復(fù)合層,提升渲染性能。
新建圖層的時(shí)候要注意:GPU 不僅需要發(fā)送渲染層圖像到GPU ,而且還需存儲(chǔ)它們,以便稍后在動(dòng)畫中重用。不能隨意的創(chuàng)建圖層,一定要結(jié)合當(dāng)前項(xiàng)目的情況去分析。因?yàn)閯?chuàng)建一個(gè)新的層是有代價(jià)的,每創(chuàng)建一個(gè)新的渲染層,就意味著新的內(nèi)存分配和更復(fù)雜的層管理。對(duì)于使用移動(dòng)設(shè)備的用戶來說是一個(gè)很大的負(fù)擔(dān)。
一、存儲(chǔ)介質(zhì)
Cookie:cookie一般用來存放賬戶驗(yàn)證的的信息或者一些比較敏感的用戶數(shù)據(jù),又或者是在移動(dòng)端中一些項(xiàng)目的合作頁面需要獲取登錄態(tài)的信息時(shí)候,就可以用一個(gè)中轉(zhuǎn)頁的cookie來存放相應(yīng)的數(shù)據(jù),以便獲取。總的來說就是,用于C-S之間交互和本身數(shù)據(jù)存儲(chǔ)。因?yàn)椋膫鬟f方式是先從服務(wù)器生成,然后瀏覽器在收到服務(wù)器的返回?cái)?shù)據(jù)中header中的set-cookie把數(shù)據(jù)寫到本地,接著每次http請(qǐng)求(同域名下)都會(huì)夾帶cookie信息,從而讓服務(wù)器進(jìn)行請(qǐng)求的用戶驗(yàn)證
這是一個(gè)非常高效的交互機(jī)制,但是這也帶來了一些問題既然每次都會(huì)帶上cookie那么說明如果請(qǐng)求數(shù)量多就會(huì)帶來流量上的消耗,會(huì)造成加載的速度慢和資源浪費(fèi),一些資源可以用cdn解決把主站和資源站的域名分開,當(dāng)然這也是建立在量大的網(wǎng)頁的情況下,如果一個(gè)網(wǎng)頁的PV還不到10萬以上那其實(shí)以今天的網(wǎng)絡(luò)來說這點(diǎn)也可以忽略不計(jì)。說到這里,這讓我想起了以前去一些小公司面試的時(shí)候,當(dāng)我問到他們公司web性能優(yōu)化一塊的時(shí)候,那些技術(shù)負(fù)責(zé)人基本上就是一句話,“流量還沒到10萬以上的話,能看到界面正常體驗(yàn)就行,怎么方便怎么來。“大家就哈哈的一笑。不過作為開發(fā)者還是要從技術(shù)的角度出發(fā),無論項(xiàng)目大小,盡可能做到最好。
localStrage & sessionStrage:相對(duì)于cookie這個(gè)兩個(gè)是H5新出的專門用于存儲(chǔ)數(shù)據(jù)的屬性,容量可以達(dá)到5M,唯一的區(qū)別就是一個(gè)是關(guān)閉后數(shù)據(jù)還在,另一個(gè)是瀏覽器關(guān)閉后數(shù)據(jù)清空。可以作為一些臨時(shí)數(shù)據(jù)的存放,例如表單或者購物車數(shù)據(jù)等。
IndexDB:這個(gè)瀏覽器的API,是一個(gè)瀏覽器數(shù)據(jù)庫,在需要存儲(chǔ)大量的結(jié)構(gòu)化數(shù)據(jù)的時(shí)候才需要使用,目前使用這個(gè)API的還是很少的,因?yàn)樵诳蛻舳诉€不要存儲(chǔ)特別量大的數(shù)據(jù),數(shù)據(jù)基本是交給后臺(tái)的,前端基本上需要存儲(chǔ)的數(shù)據(jù)基本上就是臨時(shí)數(shù)據(jù)和驗(yàn)證數(shù)據(jù)。indexDB另一個(gè)是創(chuàng)建相應(yīng)的離線應(yīng)用。
Server Worker:這個(gè)是用于需要獲取體積大和計(jì)算量很大的js文件的時(shí)候需要用到,在3D渲染的情況下,js的文件體積很大,計(jì)算量也很大,而js又是單線程的執(zhí)行。這就有可能出現(xiàn)卡頓的情況,上一個(gè)js沒處理完,下一個(gè)js就得等,SW就是獨(dú)立于當(dāng)前WEB,在后臺(tái)可以對(duì)不同的JS進(jìn)行處理,主頁面進(jìn)行監(jiān)聽最后再進(jìn)行匯總。下面是SW的生命周期:
PWA:progressive web app指的是一種新型的app模型,通過一系列的web新特性配合UI設(shè)計(jì)達(dá)到最好的用戶體驗(yàn)。這也是未來WEB APP的趨勢(shì)。說白一點(diǎn),就是會(huì)盡量的貼近原生APP的體驗(yàn)度,例如他的三個(gè)主要方向,第一在沒有網(wǎng)絡(luò)的情況下也可以打開APP進(jìn)行使用。其二是提高相應(yīng)速度,達(dá)到最好的體驗(yàn)效果,另外一個(gè)是生成桌面可點(diǎn)擊應(yīng)有,就是和普通的APP一樣,通過點(diǎn)擊APP進(jìn)入一樣有全屏和推送的功能。
瀏覽器緩存一個(gè)好的緩存策略可以減少http請(qǐng)求和網(wǎng)頁的延遲,減少不必要的數(shù)據(jù)加載,降低網(wǎng)絡(luò)負(fù)荷,從而提高頁面的反應(yīng)速度,能讓用戶有更好的瀏覽體驗(yàn)。但是,緩存只能提高第二次打開頁面的反應(yīng)速度,第一次打開頁面還是得由當(dāng)前網(wǎng)絡(luò)環(huán)境和設(shè)備來決定。瀏覽器的緩存是將文件保存在客戶端,當(dāng)每次會(huì)話時(shí),瀏覽器都會(huì)去檢查緩存的副本是不是還在有效期之內(nèi)。如果是,則瀏覽器不會(huì)再向服務(wù)端請(qǐng)求文件,而是直接在內(nèi)存中獲取并且使用。如果文件已經(jīng)過期,那么瀏覽器才會(huì)向服務(wù)端發(fā)起請(qǐng)求。這樣就能減少不必要的請(qǐng)求,加快頁面的相應(yīng)。
web緩存的信息會(huì)保存在httpheader中,通過httpheader中的一些屬性去配置一些緩存策略,通過這里策略來決定資源是否需要再次向服務(wù)端發(fā)起請(qǐng)求加載。可以存在于responseheader中也可以存在于requestheader中,目的就是讓客戶端和服務(wù)端知道相互的一個(gè)緩存情況。
Cache-control是控制緩存策略的httpheader,這里面有:max-age,s-maxage, private,public,no-cache,no-store通過這些屬性來進(jìn)行一個(gè)緩存的配置,形成一個(gè)緩存的策略。
max-age:max-ago指的是最大的有效時(shí)間,即資源從當(dāng)前請(qǐng)求的時(shí)間開始在這個(gè)時(shí)間范圍之內(nèi),不需要向服務(wù)器發(fā)起資源請(qǐng)求,瀏覽器直接獲取內(nèi)存的文件使用即可,我們打開王者榮耀的官網(wǎng):
看到這里logo,Cache-control的max-age是86400秒,換算一下86400/3600=24,也就是這個(gè)logo在一天之內(nèi),訪問這個(gè)網(wǎng)頁都不會(huì)向服務(wù)端發(fā)起資源請(qǐng)求,即使服務(wù)端的這張logo發(fā)生了變化,由圖片中可看到from memory cache,即從內(nèi)存中獲取。
s-maxage :s-maxage和max-age類似,都是在指定的時(shí)間之內(nèi)不會(huì)向服務(wù)端發(fā)起資源請(qǐng)求,但是有一點(diǎn)不同,s-maxage指向的是共享緩存(后面會(huì)進(jìn)行說明),例如:cdn,并且當(dāng)一個(gè)Cacha-control中同時(shí)設(shè)置了maxage和s-maxage之后,s-maxage會(huì)覆蓋掉maxage和Expires 。
private 和 public: private指的是私人緩存,即只能由用戶自己去訪問的緩存,而public指的是共享緩存是多個(gè)瀏覽器都可以去訪問的,如果沒有指定private或者public默認(rèn)為public,另外需要注意的是,s-maxage必須設(shè)置public的情況下才可以生效。
no-cache:指的是每一次都會(huì)想服務(wù)端發(fā)起請(qǐng)求驗(yàn)證緩存是否過期失效,而不是向maxage那樣,在一段內(nèi)就不會(huì)向服務(wù)器發(fā)起資源的請(qǐng)求。no-cache的用法上要注意一點(diǎn),可以將maxage設(shè)置為0,并且屬性設(shè)置為private:
Cache-control:private,maxage:0,no-cache
no-store指的就是禁止緩存,每次加載都需要進(jìn)行資源的請(qǐng)求。
Expires:Expires是用來設(shè)置緩存過期時(shí)間的,他和max-age一樣,都是指定都某個(gè)時(shí)間之內(nèi),只要緩存生效就不會(huì)向服務(wù)器請(qǐng)求資源,但是,max-age的優(yōu)先級(jí)要高于expires,且需要和last-modified一起使用,因?yàn)椋琫xpires是強(qiáng)緩存,他在指定的時(shí)間之內(nèi)是不是向服務(wù)端發(fā)起請(qǐng)求的,不管文件是否再服務(wù)器端發(fā)生了更新。還有一點(diǎn)Expires它相對(duì)來說出現(xiàn)得比較早,所以他在瀏覽器兼容方面是有優(yōu)勢(shì)的。
Last-modified&if-last-modified:last-modified&if-last-modified指的是文件最后的修改時(shí)間,是基于客戶端和服務(wù)端的緩存協(xié)商機(jī)制的 last-modified存于responseheader中 if-modifity-since存于requestheader中
我們看到了responseheader中有一個(gè)last-modified中有一個(gè)時(shí)間,這是時(shí)間就是服務(wù)器上這個(gè)文件的最后修改時(shí)間,瀏覽器會(huì)把這個(gè)時(shí)間保存下來,當(dāng)下次請(qǐng)求的的時(shí)候,requestheader中if-modified-since就會(huì)有這個(gè)時(shí)間,告訴服務(wù)器我這個(gè)文件,最后更新的是這個(gè)時(shí)間點(diǎn)。如果,此時(shí)服務(wù)端的文件已經(jīng)發(fā)生了改變,那么他就會(huì)重新加載,返回狀態(tài)碼200,如果,服務(wù)端的資源沒有改變,那么瀏覽器端則會(huì)直接獲取緩存,返回304。
Etag 和 if-none-Match:由服務(wù)器端根據(jù)文件的內(nèi)容生成一個(gè)hash值,來標(biāo)識(shí)資源的狀態(tài),第二次向服務(wù)端發(fā)起請(qǐng)求時(shí),服務(wù)端會(huì)驗(yàn)證hash是否一致,來判斷文件是否發(fā)生了變化,他可以解決什么問題? 僅有l(wèi)ast-modified的情況下會(huì)以下的缺陷:
服務(wù)器文件變化了,但是內(nèi)容沒有變化;
服務(wù)器不能精確的獲取資源的最后修改時(shí)間;
資源在秒以內(nèi)進(jìn)行了操作,last-modified是不能識(shí)別的;
Etag就是以內(nèi)容為基準(zhǔn),不管有什么操作,只要內(nèi)容變化,hash值一定發(fā)生變化。 另外一個(gè)是,etag的優(yōu)先級(jí)要比last-modified的優(yōu)先級(jí)要高。再補(bǔ)充一點(diǎn):Last-modified&ETag是在瀏覽器進(jìn)行再一次驗(yàn)證的時(shí)候,才會(huì)使用到,他要先判斷緩存過期的情況下(max-age),再來使用這兩個(gè)東東,當(dāng)然ETag的優(yōu)先級(jí)是高過Last-modifity的。
緩存策略定制:
緩存策略我把它歸為兩大類,一是靜態(tài)資源的緩存策略,而是動(dòng)態(tài)資源的緩存策略,后續(xù)可能還會(huì)有新的方法,我到時(shí)再把它寫出來。先注意一點(diǎn),對(duì)于緩存要先分好是共享的還是私人的,一來避免被代理緩存,二來,養(yǎng)成良好注意代碼規(guī)范的習(xí)慣。
靜態(tài)資源:靜態(tài)資源指的就是css,javascript,txt,圖片等固定不會(huì)修改的文件。像css,javascript這樣的文件,我們?cè)诖虬臅r(shí)候是會(huì)指定版本號(hào)的,也就是有一個(gè)名字都有一個(gè)后綴,一旦發(fā)生了變化,整個(gè)文件也就更新了。所以,對(duì)于靜態(tài)資源來說緩存的策略就比較簡單,以當(dāng)前項(xiàng)目的情況,做一些適當(dāng)?shù)男薷募纯伞?/p>
動(dòng)態(tài)資源: 動(dòng)態(tài)資源呢,就例如股票,期貨等的價(jià)格信息,這里資源是共享資源,瀏覽器在每次是有他們的時(shí)候?yàn)g覽器或者代理服務(wù)器都會(huì)去檢查是否有最新的版本,那么,我們可以這樣設(shè):
Cache-control:public,no-cache,no-store
對(duì)于有些數(shù)據(jù)可以保存一段時(shí)間的,那就max-ago=...(秒),根據(jù)需要換算一下就可以了,例如:緩存有效一小時(shí)
Cache-control:public,max-age=86400
一個(gè)小時(shí)之后,需要嚴(yán)格的控制緩存,再次請(qǐng)求則可以使用:
Cache-control:public,max-age=86400,no-cache or must-revalidate
其實(shí)也是根據(jù)需求來吧,設(shè)置無外乎多一條命令而已。
Vary:Accept-Encoding 這個(gè)是針對(duì)于那些啟用了gzip壓縮且被代理服務(wù)器緩存的資源,如果客戶端不支持壓縮,那么這種情況下可能會(huì)得不到正確的數(shù)據(jù),這樣代理服務(wù)器可能會(huì)出現(xiàn)兩個(gè)版本的資源,一個(gè)是壓縮過的,另一個(gè)是未經(jīng)過壓縮的。另一個(gè)原因是ie瀏覽器,ie不支持任何帶有Very頭,但值不為Accept-Encoding 和 user-Agent的資源
總結(jié):頁面的優(yōu)化方案需要根據(jù)當(dāng)前項(xiàng)目的需求進(jìn)行調(diào)整,達(dá)到實(shí)際體驗(yàn)最佳的即可。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/98121.html
摘要:如下圖所示一重繪與回流前端性能優(yōu)化最關(guān)鍵的就是減少頁面的重繪與回流。很明顯就是少了一步,這是因?yàn)榘褧?huì)觸發(fā)回流的屬性用替代,這樣就使渲染的過程減少了這一步,使渲染的時(shí)間減少從而提高性能。 我們今天來說說前端圖形渲染優(yōu)化,因?yàn)槲医酉聛淼臅r(shí)間可能要開始研究webgl方面的東西,所以就在這里把之前做過的H5做一個(gè)總結(jié),現(xiàn)同步發(fā)布于GERRY_BLOG,TiMiGerry-知乎,轉(zhuǎn)載請(qǐng)保留鏈接。...
摘要:在減少文件請(qǐng)求數(shù)量方面大致有以下三方面合并腳本文件合并樣式文件合并引用的圖片,使用雪碧圖。和的模塊管理不同,前者是基于靜態(tài)的,而后者是動(dòng)態(tài)的。被打包文件的內(nèi)容也已經(jīng)被壓縮混淆,減少了加載文件的。 作者:劉軼斌,騰訊應(yīng)用開發(fā) 工程師商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系騰訊WeTest獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 原文鏈接:http://wetest.qq.com/lab/view/345.html We...
摘要:摘要彈性裸金屬服務(wù)器的八大特性,總結(jié)相關(guān)特性。那么阿里云彈性裸金屬服務(wù)器神龍的表現(xiàn)呢在這里我們定義的彈性裸金屬服務(wù)器是一個(gè)新物種,它強(qiáng)調(diào)的是彈性,也就是通過技術(shù)創(chuàng)新,使得傳統(tǒng)裸金屬服務(wù)能夠做到和虛擬機(jī)一致的使用體驗(yàn)和業(yè)務(wù)敏捷。 摘要: 彈性裸金屬服務(wù)器的八大特性,總結(jié)相關(guān)特性。那么阿里云彈性裸金屬服務(wù)器(神龍)的表現(xiàn)呢 在這里我們定義的彈性裸金屬服務(wù)器是一個(gè)新物種,它強(qiáng)調(diào)的是彈性,也就...
閱讀 1360·2019-08-30 15:44
閱讀 2106·2019-08-30 11:04
閱讀 526·2019-08-29 15:17
閱讀 2544·2019-08-26 12:12
閱讀 3136·2019-08-23 18:09
閱讀 925·2019-08-23 15:37
閱讀 1525·2019-08-23 14:43
閱讀 2928·2019-08-23 13:13