javascript
JS缓存与浏览器缓存技术详解 学习笔记
緩存與瀏覽器緩存技術:
一,緩存:
緩存是網絡傳輸中常用到的一種技術,利用緩存可以讓我們在數據傳輸方面更加的方便和快捷。
1.1緩存的優點:
避免冗余的數據傳輸:
當很多的人去訪問一個網站的原始服務器,此時原始服務器會為每個訪問著者都發送一份相同的文本。這樣就會浪費我們的網絡帶寬,同時使我們的原始服務器負載加重。假如使用了緩存,此時我們就可以在緩存服務器中備份一份文本,此時再有訪問者訪問就不用直接和原始服務器對接,讓緩存去發送文本。這樣可以減少我們的原始服務器的負載壓力,同時可以避免一些不必要的數據傳輸。
緩解帶寬瓶頸:
緩存還可以緩解帶寬瓶頸。我們都知道在網絡傳輸中,數據的傳輸速率會以路徑中最小的的帶寬來計算。而大多數的網絡一般為本地網絡提供的帶寬是大于遠程網絡的帶寬。當我們在本地做了緩存之后就不用遠程的去向原始服務器請求數據,則避免了遠距離傳輸數據時受到小帶寬的限制,這樣我們就利用局域網的較大帶寬來傳輸文本。
避免瞬間擁塞:
瞬間擁塞問題其實很考驗原始服務器的抗壓能力,當在網絡上有一個熱點問題的時候,會在短時間內有巨大的點擊量,這樣服務器不得不在但時間內處理百萬計的網絡請求。如果我們不做緩存處理,那么這樣的對原始服務器的考驗是巨大的。如果我們做了緩存,用戶沒有必要向服務器請求一些非必要的數據或者文本,這樣對于原始服務器來說是一個極大的幫助,減少了服務器去接收訪問的數據的次數。
距離延遲:
數據傳輸的過程中,當發送者和接收者兩者的距離很遠,那么數據傳輸帶來的延遲就越明顯。即使是光速傳輸,也會存在延遲,而緩存能夠讓遠距離數據傳輸變得很低。
二,命中和未命中:
? 可以用緩存服務器中已有的副本來為客戶端的請求提供服務,這種行為稱為緩存命中,其實緩存命中的簡單理解就是客戶端從緩存中拿到了它想要的數據。反之被稱作緩存未命中。
2.1再驗證:
當我們的緩存服務器緩存原始服務器發來的數據時,經過一段時間后,原始服務器的內容可能會因為某些需求而發生改變。緩存要不定時的對緩存的數據進行檢測,來確定我緩存的數據是不是最新的數據。這些新鮮度檢測被成為HTTP再驗證。為了有效的進行在驗證,HTTP定義了一些特殊的請求,不用從服務器上獲取整個對象就可以檢測出是否是最新數據。
通常情況下,緩存服務器并不會去主動的去向原始服務器發送請求來驗證數據是否是最新的,原因在于這樣會消耗一定的帶寬,假如一個緩存服務器中有百萬量級的存儲文本,那么去驗證一次需要消耗大量的資源。那么什么時候采取驗證呢,一般情況下是用戶發起請求的時候緩存服務器去向原始服務器發送驗證請求。其實這里注意一下,并不是只要用戶發起請求緩存服務器就發送驗證請求的,是有前提條件的。這種前提條件我們后面會詳細的講到。
緩存服務器在對緩存進行驗證的時候會向原始服務器發送一個小小的請求,這個請求的數據量其實是很小的。原始服務器會根據現有的數據來對請求進行回應。
HTTP為我們準備了幾個用于再驗證的工具,后面將會講到,而最常用的是If-Modefied-Since首部,該首部的值是一個日期,該日期是該文件最后更改的日期。原始服務器會對請求進行回應,通常有以下三種情況:
再驗證命中:
如果服務器文件未被修改,服務器會以一個304 Not Modified進行響應。只要緩存知道文本有效,那么就暫時將原來存儲的副本標記為有效,并將副本提供給客戶端,這個過程被稱為:再驗證命中。
再驗證未命中:
如果原始服務器的數據已經改變,此時原始服務器會把最新的文本發送給客戶端,然后返回200 OK,然后緩存服務器會拷貝一份最新的文本進行緩存。
文本被刪除:
當我們再驗證的文本已經被刪除,服務器會返回404 Not Found進行響應。緩存服務器也會將其副本刪除。
2.2區分命中和未命中的情況:
通常情況下,我們僅憑借狀態碼是無法分清我們請求的數據是否是命中或者未命中。也就是說,我們并不知道我們的獲取的數據是來自緩存服務器還是原始服務器。因為我們獲取到數據后的狀態碼都是200 OK。其實我們可以通過其他的響應頭來判別該數據是從緩存中獲取還是原始服務器。比如:Last-Modified字段,如果該字段的值比較早,那么就是從緩存中獲取。
三,緩存的拓撲結構:
緩存的種類一共有兩種:私有緩存和公有緩存。
3.1私有緩存:
其實私有緩存是一對一的關系,也就是為一個用戶來服務。私有緩存不需要很大的存儲空間。其實瀏覽器內部的緩存就是私有緩存。大多數的瀏覽器有自己內建的私有緩存,瀏覽器通常會把常用的文檔緩存到我們的個人電腦的磁盤和內存當中。
3.2公有緩存:
公有緩存是特殊的共享代理服務器,被稱為代理緩存。代理緩存的一大特點是它與用戶的關系是一對多的,公有緩存一般是為一個集體服務的,把這個集體經常訪問的數據緩存到公有緩存當中,這樣的好處是公有緩存能夠提供給多個用戶的請求,可以減少冗余的流量。和私有緩存相比,公有緩存可以減少更多的再驗證請求,比如要驗證一個數據的新鮮度。對于私有緩存來說,每次都要向原始服務器發送驗證請求,有100個用戶就要發送一百個請求。而對于公有緩存來說,只要有一個數據過期,那么只需要驗證一次,然后將最新的數據緩存到緩存服務器當中,當其他的用戶去請求這個資源的時候可以直接從緩存服務器當中來獲取最新的數據,不用再經行驗證了,原因就在于別人已經讓緩存服務器驗證過了。
四,緩存的處理步驟:
我們處理緩存的時候大致可以分為七步:接收,解析,查詢,新鮮度檢驗,創建響應,發送,日志。接下來我們細說每一步在緩存中扮演的角色。
4.1接收:
通常情況下,當我們向一個站點發送一個資源請求的時候,會先向緩存服務器發該資源的資源請求,緩存服務器會從網絡中讀取抵達緩存服務器的資源請求報文。
4.2解析:
當緩存服務器接收到報文后,緩存將請求報文解析成片段,將首部的各個部分放入易于存儲的數據結構中,這樣緩存就可以更容易處理首部字段并修改它們了。
4.3查找:
在這一步中,緩存會獲取到URL,此時緩存會在緩存服務器中查找該數據。查詢的結果通常有兩種,一是緩存服務器以前緩存過該數據。二是緩存服務器里并沒有這個數據。當緩存服務器沒有該數據的時候會向原始服務器發送請求,該請求的報文是在客戶端的請求報文基礎上的改進。然后原始服務器會將請求的數據返回給緩存服務器,緩存服務器將該數據復制一份然后保存,并保存原始服務器的響應報文。如果緩存服務器中有該數據,則接下來對其進行新鮮度檢測。
4.4新鮮度檢測:
HTTP可以通過一些響應頭字段將發送給緩存服務器的文檔在緩存服務器保存一段時間,在這段時間內,我們可以認為該文檔副本是新鮮的,緩存服務器可以在不聯系原始服務器的情況下向客戶端直接提供該文檔。但是一旦過了這段時間,我們就認為該文檔是不新鮮的,當客戶端去請求該文檔的時候,緩存服務器必須向原始服務器發送再驗證請求。
4.5創建響應:
我們希望緩存服務器的響應看起來就像是原始服務器的響應一樣,所以緩存服務器會將原始服務器的響應緩存到自己的內存當中。緩存服務器在向客戶端進行響應的時候,它會在創建響應的時候會將原始服務器的響應首部作為緩存服務器響應首部的起點,然后對這些基礎首部進行了修改和擴建。
4.6發送:
一旦響應首部準備好了,緩存服務器就將響應報文和數據返回給客戶端。
4.7日志:
大都數緩存都會保存日志文件以及與緩存相關的一些統計數據。
4.8緩存處理流程圖:
五,如何讓備份數據在緩存服務器中保存一段時間:
5.1文檔過期:
通過HTTP的Cache-Control和Expires,HTTP讓原始服務器向每一個文檔都添加了一個"過期時間",可以比作商品的保質期。在這段時間內我們可以認為文檔是新鮮的,在文檔過期之間,緩存服務器可以任意的使用這些副本為不需要與服務器聯系,但是假如客戶端必須讓緩存服務器與原始服務器聯系就另當別論了。
5.2過期時間和使用期:
在HTTP協議中 ,我們可以使用Cache-Control和Expires來為一個資源設置它在緩存服務器中的新鮮度保存時間,兩者的本質是一樣的,都是來設置時間。但是在形式上是不同。
- Cache-Control:格式:Cache-Control : max-age = 3600,該字段的值的單位是秒,max-age定義了文檔最大的使用期限。從第一次生成文檔到文檔不在新鮮,無法使用為止。
- Expires:這個響應頭的字段就比較簡單了,就是指定一個過期的時間。當超過了指定的時間就認為該文檔不新鮮了。
在實際的應用當中,使用最多的是Cache-Control。當我們設置了文檔的過期時間后,客戶端對該數據的請求就由緩存服務器來處理,不用通知原始服務器。
5.3服務器再驗證:
可能有人會有疑問,當我們的文檔假如過期之后會怎么辦呢。當客戶端向緩存服務器去請求文檔時,發現該文檔的保質期已經過了,文檔的保質期過了并不代表他不能再用了,時間過期只是代表該到進行文檔核對的時間了,此時它會向服務器發送再驗證請求進行文檔的再驗證。
- 如果再驗證顯示內容發生了變化,緩存會獲取一份新的文檔副本,并將其儲存在舊文本的位置上,然后將文本發送給客戶端。當然這個發送的過程包括了我們說的響應的創建和發送等細節。
- 如果再驗證顯示內容并沒有發生變化,那么緩存只獲取新的首部,包括一個新的過期日期,然后將自己緩存的文案發給客戶端連同緩存修改和擴充過的響應頭。
六,如何進行再驗證:
我們以瀏覽器為例,其實再驗證是瀏覽器內部自己實現的內置功能,不需要我們去進行上面所講的一系列操作,比如緩存處理的七個步驟,新鮮度的檢查以及我們現在要說的再驗證。這是針對瀏覽器來說的。可能其他設備有所不同。那么瀏覽器是如何實現再驗證的呢?
用條件方法進行再驗證。HTTP允許向原始服務器發送一個條件GET。我們向get請求報文中添加一些特殊的條件首部就可以發起條件GET。
HTTP定義了5個條件請求首部。對緩存再驗證來說最有用的有兩個:If-Modified-Since和If-None-Match。每一個條件首部對應著一個再驗證機制。
6.1 If-Modified-Since/Last-Modified再驗證:
If-Modified-Since和Last-Modified是配套使用的。當瀏覽器發送一個條件GET時,該請求報文首部有一個If-Modified-Since字段,而這個字段是文檔最后更改的日期,當原始服務器接收之后,提取If-Modified-Since字段的值,然后和Last-Modified的值進行對比。假如時間不一致說明原始服務器中的數據已經被修改過了,此時會返回一個最新的文檔和一個響應報文,響應首部的狀態碼為:200 OK,其中還包括一個新的文檔過期時間和最近一次文檔修改的時間(即Last-Modified字段),而這個修改的時間就是下一次瀏覽器緩存再發一個條件GET時If-Modified-Since的值。當接收到新的文檔時瀏覽器緩存會備份該文檔,然后對收到的原始服務器的響應首部進行修改和擴充發送給客戶端。假如對比If-Modified-Since和Last-Modified一致,說明原始服務器中的數據并沒有修改過,此時服務器會返回304 Not Modified,還有一個新的過期時間。**這里原始服務器只會返回響應頭,不會返回響應體。**當瀏覽器緩存接收到該響應時會將以前緩存的文檔發送給客戶端,并向客戶端發送304 Not Modified,表示并沒有從原始的服務器中獲取數據。這里注意以下,這里返回的是304 Not Modified而不是200 OK,后者出現的第一種情況是出現文檔還在保質期內,直接從緩存中獲取。第二種的情況是文檔保質期過了,并且文檔被修改過,然后向原始服務器要最新的文檔。
6.2 If-None-Match實體標簽再驗證:
If-None-Match和ETag搭配著使用。其實和If-Modified-Since/Last-Modified再驗證的思想一樣,都是通過比對來判斷文檔是否已經被修改過。其實ETag本質上相當于一個字符串表示符,你可一把他賦值為一串數字字符串來代表現在這個文檔的版本號,當文檔被改變的時候可以修改ETag來表示文檔已經更新。當瀏覽器使用If-None-Match來進行再驗證的時候,服務器會獲取If-None-Match的值來與ETag進行對比。如果內容一致,說明文檔并沒有發生改變,然后返回304 Not Modefied,還有一個新的過期時間,瀏覽器緩存的動作與``If-Modified-Since的動作一致。對比后發現如果不一致說明文檔被修改過了,此時會返回一個最新的文檔和一個新的過期時間。瀏覽器緩存的動作和上面再驗證的動作一樣。也是先將文檔緩存,然后返回給客戶端,并返回304 Not Modified`。
6.3注意:
我們要把If-Modified-Since/Last-Modified,If-None-Match/ETag與Cache-Control/Expires區分開來。Cache-Control/Expires是用來設置過期時間的。而If-Modified-Since/Last-Modified,If-None-Match/ETag是用來當過期時間到了之后進行再驗證的。
七,瀏覽器緩存:
其實當你了解了緩存機制之后就不在對瀏覽器緩存感到陌生了,本質上瀏覽器緩存和服務器緩存(或者叫做緩存服務器本質上是一樣的)。只不過瀏覽器廠商在瀏覽器內部實現了自己的緩存機制,可以看作一個小型的緩存服務器。
7.1瀏覽器緩存的分類:
瀏覽器緩存可以分為兩種:強緩存和協商緩存。可能這個時候就有同學有疑問了,不是說好了和緩存相似嗎,為什么這兩種緩存沒有見過呢。我們往后講就知道了。
7.1.1強緩存(Expires&Cache-control):
- 當瀏覽器對于某個資源的請求命中了強緩存,返回的http狀態碼為200,在chrome的開發者工具的network面板里面size會顯示from cache。
- 強緩存是利用Expires和Cache-Control這兩個請求頭字段來實現的,它們都表示資源在客戶端(這里指的是瀏覽器緩存)的有效期。
- Expires表示的是一個資源過期的時間的請求頭字段,它描述的是一個絕對的時間,由服務器返回,GMT格式來表示,在這段時間瀏覽器不用向原始服務器發送任何請求。
- Expires緩存原理如下:
- 瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,會在響應頭上添加Expires。(其實瀏覽器會先向瀏覽器緩存發送請求)。
- 瀏覽器在接收到這個資源后會把這個資源連同所有的響應頭一起緩存下來,所以強緩存命中的響應頭并不是來自原始服務器,而是來自瀏覽器緩存中的響應頭。
- 瀏覽器再一次請求這個資源的時候,先從緩存中尋找,找到這個資源后,拿出Expires的值與現在的時間對比,如果在Expires的時間保質期內,那就命中強緩存,否則沒有命中緩存。
- Expiress是一個比較古老的技術,而現在使用的是Cache-Control,這是一個相對時間,它的值是數值,表示資源有效期的秒數。瀏覽器在對待Cache-Control的行為和Expires是一樣的。
7.1.2協商緩存(Last-Modified/If-Modified-Since&ETag/If-None-Match):
- 當瀏覽器對某個資源沒有命中強緩存的時候,就會發送一個請求到服務器,驗證協商緩存是否命中,如果協商緩存命中,響應頭返回的http狀態碼為304,并且會顯示一個Not Modified的字符串。
- 協商緩存是是利用[If-Modified-Since/Last-Modified],[If-None-Match/ETag]這兩個請求響應頭來管理的。
- 協商緩存和強緩存不一樣,強緩存不發請求到服務器,所以有時候資源更新了瀏覽器并不知道,但是協商緩存會發請求到原始服務器,所以資源是否更新,瀏覽器也可以知道。
八,對比:
其實我們通過上面對瀏覽器緩存的描述,我們可以發現,其實瀏覽器緩存中的兩個緩存機制是和我們普通的緩存是有很大關系的。強緩存的本質就是文檔沒有過保質期時緩存服務器和客戶端的一些列動作。而協商緩存就是緩存服務器再驗證的過程。其實瀏覽器緩存本身可以看作是一個緩存服務器,只不過它內嵌在瀏覽器當中了。緩存服務器的絕大多數特性都可以適用于瀏覽器緩存。
總結
以上是生活随笔為你收集整理的JS缓存与浏览器缓存技术详解 学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue父子组件传值:异步传输数据的问题
- 下一篇: KiCad 下载安装及镜像站介绍