一、瀏覽器緩存
這一點主要解析瀏覽器緩存以及緩存機制的詳細過程。
與緩存相關(guān)的狀態(tài)碼:
200 ok?? ?從瀏覽器下載的最新資源
200 (from memory cache)?? ?不進行http請求,直接從瀏覽器內(nèi)存中讀取的資源,頁面關(guān)閉,則資源釋放,一般一些腳本、圖片、文字等會存在內(nèi)存中
200 (from disk cache)?? ?不進行http請求,直接從磁盤中讀取的資源,頁面關(guān)閉,資源仍然存在,除非清除緩存,一般一些非腳本文件會存在磁盤中,例如html、css文件
304 (not modified)?? ?請求了服務器,但是由于服務器資源沒有更新,所以仍使用內(nèi)存中的資源
緩存相關(guān)的http header介紹:
http header?? ?介紹
cache-control?? ?response header or request header;指定緩存機制,優(yōu)先級最高
expires?? ?response header or request header;指定緩存的過期時間(現(xiàn)在瀏覽器一般設(shè)置cache-control,設(shè)置expires是為了兼容http1.0)
last-modified?? ?response header;資源的最后修改時間
etag?? ?response header;資源的唯一標識符
if-modified-since?? ?request header;緩存的服務器資源的最后修改時間
if-none-match?? ?request header;緩存的服務器資源的唯一標識
1.1強緩存:
不會進行http請求,讀取的是內(nèi)存中的資源,直到緩存失效
涉及到的狀態(tài)碼:
200(from memory cache)
200(from disk cache)
涉及到的http header:?
cache-control
expires
當瀏覽器對某個資源的請求命中了強緩存時,返回的http狀態(tài)碼為200,在chrome開發(fā)者工具中的network中的size會顯示from cache
強緩存時利用Expires或者Cache-Control這兩個http header實現(xiàn)的,都用來表示資源在客戶端緩存的有效期
Expires是http1.0提出的一個header,描述的是一個絕對時間,由服務器返回,用GMT格式的字符串表示,如Exprires:Thu,31 Dec 2037 23:55:55 GMT
緩存過程:
1、瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在response的header加上Expires的header
2、瀏覽器在接收到這個資源后,會把這個資源連同所有的response header一起緩存下來,所以緩存命中的請求返回的header并不是來自服務器,而是來自之前緩存的header
3、瀏覽器再請求這個資源時,先從緩存中尋找,找到這個資源后,拿出Expires跟當前的請求時間比較,如果請求時間在Expires指定的時間之前,就能命中緩存,否則就不行。
4、如果緩存沒有命中,瀏覽器直接從服務器加載資源時,Expires Header在重新加載的時候會被更新
Expires是服務器返回的一個絕對時間,在服務器時間與客戶端時間相差較大時,緩存管理容易出現(xiàn)問題,比如隨意修改下客戶端時間,就能影響緩存命中的結(jié)果,所以在http1.1的時候,提出了一個新的header,也就是Cache-Control,這是一個相對時間,在進行緩存命中的時候,都是利用客戶端時間進行判斷,因此更有效安全一些,在配置緩存的時候,以秒為單位,用數(shù)值表示:如:Cache-Control:max-age=315360000,它的緩存過程是:
1、瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在response的header加上Cache-Control的header
2、瀏覽器在接收到這個資源的時候,會把這個資源連同所有response header一起緩存下來
3、瀏覽器再次請求這個資源的時候,先從緩存中尋找,找到這個資源之后,再拿這個過期時間跟當前的請求時間比較,如果請求時間在過期時間之前,就能命中緩存,否則就不行。
4、如果緩存沒有命中,瀏覽器直接從服務器加載資源時,Cache-Control在重新加載的時候會被更新
cache-control
優(yōu)先級最高,所有的緩存機制看到 cache-control 都要服從它;在請求頭和響應頭中都可以設(shè)置;cache-control有多種設(shè)置,設(shè)置如下:
cache-control?? ?描述
no-store?? ?請求和響應都不緩存(禁用)
no-cache?? ?協(xié)商緩存,相當于cache-control:max-age=0(每次取之前先跟服務器溝通比較)
max-age?? ?指定緩存內(nèi)容將在xxx秒后失效
public?? ?所有內(nèi)容都將被緩存(客戶端和代理服務器都可緩存)
private?? ?所有內(nèi)容只有客戶端可以緩存,Cache-Control的默認取值
注意:這個header可以只用一個,也可以同時用兩個,同時存在時,Cache-Control優(yōu)先級高于Expires
1.2 強緩存的管理
兩種方式來設(shè)置是否啟用強緩存:
1、通過代碼的方式,在web服務器返回的響應中添加Expires和Cache-Control Header
2、通過配置web服務器的方式,讓web服務器在響應資源的時候統(tǒng)一添加Expires和Cache-Control Header
1.3 強緩存的應用
強緩存是前端性能優(yōu)化最有力的工具,對于有大量靜態(tài)資源的網(wǎng)頁,一定要利用強緩存,提高響應速度,通常是為這些靜態(tài)資源全部配置一個超時時間超長的Expires或Cache-Control,這樣用戶只會在第一次訪問網(wǎng)站時加載靜態(tài)資源,其他時間只要緩存沒有失效并且用戶沒有強制刷新的條件下都會從緩存中加載。
然而這種緩存配置方式會帶來一個問題,就是當資源更新時,客戶端由于有緩存不會向服務器請求最新的資源,這個問題已有解決方案:
通過更新頁面中引用的資源路徑,讓瀏覽器主動放棄緩存,加載新資源。
但要實現(xiàn)有更新的文件才需要瀏覽器重新加載,因此必須讓url的修改與文件內(nèi)容相關(guān)聯(lián),利用數(shù)據(jù)摘要算法對文件求摘要信息,摘要信息與文件內(nèi)容一一對應,這一點許多前端構(gòu)建工具都做到了,如webpack
1.4 瀏覽器默認緩存使開發(fā)環(huán)境下常因為資源沒有及時更新而看不到效果
解決方法:
1、ctrl+F5
2、瀏覽器隱私模式開發(fā)
3、chrome開發(fā)者工具里將Disable cache選項打勾,阻止緩存
4、在開發(fā)階段,給資源加上一個動態(tài)的參數(shù),由于每次資源的修改都要更新引用的位置,同時修改參數(shù)的值,所以操作起來不是很方便,除非是在動態(tài)頁面比如jsp里開發(fā)就可以用服務器變量來解決,或者用前端構(gòu)建工具來處理這個參數(shù)修改的問題。
5、如果資源引用的頁面被嵌入到了一個iframe里面,可以在iframe的區(qū)域右鍵重新加載該頁面
6、如果緩存問題出現(xiàn)在ajax請求中,最有效的解決辦法就是ajax的請求地址追加隨機數(shù)
7、動態(tài)設(shè)置iframe的src時,有可能因為緩存問題導致看不到最新效果,在src后面添加隨機數(shù)即可
8、通過前端開發(fā)工具grunt gulp等的插件來啟動一個靜態(tài)服務器,則在這個服務器下所有資源返回的response header中,Cache-Control始終被設(shè)置為不緩存
1.5 發(fā)布問題
發(fā)布問題:若頁面和它引用的資源路徑同時更新了,不管是先部署頁面還是先部署資源都會帶來各種問題,這是由于資源是覆蓋式發(fā)布的,即用待發(fā)布資源覆蓋已發(fā)布資源。
解決辦法就是實現(xiàn)非覆蓋式發(fā)布:把有修改的資源文件作為一個新的文件發(fā)布,不對已有的資源文件進行覆蓋,這樣用戶還可以請求舊的資源文件,不至于發(fā)生頁面錯亂的問題,這樣先部署靜態(tài)資源,再覆蓋式部署頁面,等到用戶訪問新頁面的時候,新的資源文件也已發(fā)布,就可以正確請求,即可解決問題。
2.1 協(xié)商緩存
涉及到的狀態(tài)碼:
304 not modified
200 ok
涉及到的請求頭
etag / ig-none-match
last-modified / if-modified-since
如果命中協(xié)商緩存,請求響應返回的http狀態(tài)為304以及一個Not Modified字符串,協(xié)商緩存利用的是【Last-Modified、If-Modified-Since】、【ETag、If-None-Match】這兩對header來管理的。
【Last-Modified、If-Modified-Since】:
1、瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源時,在response的header加上Last-Modified的header,表示這個資源在服務器上的最后修改時間
2、瀏覽器再次向服務器請求這個資源時,在request的header加上If-Modified-Since的header,這個header的值就是上一次請求時返回的Last-Modified的值
3、服務器再次收到資源請求時,根據(jù)瀏覽器傳過來If-Modified-Since和資源在服務器上的最后修改時間判斷資源是否有變化,如果沒有變化則返回304 Not Modified,但是不會返回資源內(nèi)容,如果有變化就返回資源內(nèi)容,當服務器返回304 Not Modified的響應時,response header中不會再添加Last-Modified的header,因為資源沒有變化,Last-Modified的值也不變
4、瀏覽器收到304的響應后,就會從緩存中加載資源
5、如果協(xié)商緩存沒有命中,瀏覽器直接從服務器加載資源時,Last-Modofied header在重新加載的時候會被更新,下次請求時,If-Modified-Since會采用上一次返回的Last-Modified的值
這一對header都是根據(jù)服務器時間返回的,有時候會有服務器資源有變化,但最后修改時間卻沒有變化的情況,因此有了
【Etag、If-None-Match】:
1、瀏覽器第一次向服務器請求一個資源,服務器在返回這個資源的同時,在response的header加上ETag的header,這個header是服務器根據(jù)當前請求的資源生成的一個唯一標識,是一個字符串,只要資源內(nèi)容發(fā)生改變,這個字符串也會改變,跟時間沒有關(guān)系
2、瀏覽器再次請求這個資源的時候,在request的header上加上If-None-Match的header。這個header的值是上一次請求返回的ETag的值
3、服務器再次收到資源請求時,根據(jù)客戶端傳過來的If-None-Match和重新生成的該資源的新的ETag做比較,相同則返回304 Not Modified,不會返回資源內(nèi)容,如果不同則返回資源內(nèi)容,但這里即使資源沒有發(fā)生變化,也會返回ETag,因為這個ETag重新生成過,即使沒有ETag沒有變化
4、瀏覽器收到304響應后,就從緩存中加載資源
etag兩種類型:
強etag:
不論實體發(fā)生多么細微的變化都會改變其值
強ETag表示形式:"22FAA065-2664-4197-9C5E-C92EA03D0A16"。
弱etag:
弱 ETag 值只用于提示資源是否相同。只有資源發(fā)生了根本改變產(chǎn) 生差異時才會改變 ETag 。這時,會在字段值最開始處附加 W/。
弱ETag表現(xiàn)形式:W/"22FAA065-2664-4197-9C5E-C92EA03D0A16"。
注意:當etag和last-modified同時存在時則以etag為準
2.2 協(xié)商緩存的管理文章來源:http://www.zghlxwxcb.cn/news/detail-854888.html
一般服務器上的【Last-Modified、If-Modified-Since】和【Etag、If-None-Match】會同時啟用,協(xié)商緩存需要配合強緩存使用文章來源地址http://www.zghlxwxcb.cn/news/detail-854888.html
到了這里,關(guān)于瀏覽器緩存(強緩存、協(xié)商緩存)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!