文章目錄
- 1. 線程與進程
- 1.1 進程:
- 1.2. 線程:
- 1.3. 關系
- 2. 瀏覽器內核模塊組成
- 4. 事件循環機制
- 5. 緩存
- 5.1. 緩存理解
- 5.2. 緩存分類
- 5.3. 緩存使用示意圖
- 5.4. 緩存中的header參數
1. 線程與進程
1.1 進程:
進程是計算機中的程序關于某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。
1.2. 線程:
線程是操作系統能夠進行運算調度的最小單位,被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以并發多個線程,每條線程并行執行不同的任務。
1.3. 關系
每個進程都有相應的線程,在執行程序時,實際上是執行相應的一系列線程。進程是資源分配的最小單位,線程是程序執行的最小單位。
2. 瀏覽器內核模塊組成
4. 事件循環機制
模型的運轉流程:
執行初始化代碼, 將事件回調函數交給對應模塊管理
當事件發生時, 管理模塊會將回調函數及其數據添加到回調列隊中
只有當初始化代碼執行完后(可能要一定時間), 才會遍歷讀取回調隊列中的回調函數執行
5. 緩存
5.1. 緩存理解
- 緩存定義:
- 瀏覽器在本地磁盤上將用戶之前請求的數據存儲起來,當訪問者再次需要改數據的時候無需再次發送請求,直接從瀏覽器本地獲取數據
- 緩存的好處:
- 減少請求的個數
- 節省帶寬,避免浪費不必要的網絡資源
- 減輕服務器壓力
- 提高瀏覽器網頁的加載速度,提高用戶體驗
var dt = new Date();
dt.setSeconds(dt.getSeconds() + 60);
document.cookie = "cookietest=1; expires=" + dt.toGMTString();
var cookiesEnabled = document.cookie.indexOf("cookietest=") != -1;
//是否啟用cookie
if(!cookiesEnabled){alert("沒有啟用cookie ");
}else{alert("已經啟用cookie ");
}
5.2. 緩存分類
- 強緩存
- 不會向服務器發送請求,直接從本地緩存中獲取數據
- 請求資源的的狀態碼為: 200 ok(from memory cache)
- 協商緩存
- 向服務器發送請求,服務器會根據請求頭的資源判斷是否命中協商緩存
- 如果命中,則返回304狀態碼通知瀏覽器從緩存中讀取資源
- 強緩存 & 協商緩存的共同點
- 都是從瀏覽器端讀取資源
- 強緩存 VS 協商緩存的不同點
- 強緩存不發請求給服務器
- 協商緩存發請求給服務器,根據服務器返回的信息決定是否使用緩存
5.3. 緩存使用示意圖
5.4. 緩存中的header參數
強緩存的header參數
- expires:
- 這是http1.0時的規范;它的值為一個絕對時間的GMT格式的時間字符串,如
Mon, 10 Jun 2015 21:31:12 GMT
,如果發送請求的時間在expires之前,那么本地緩存始終有效,否則就會發送請求到服務器來獲取資源 - cache-control:max-age=number
- 這是http1.1時出現的header信息,主要是利用該字段的max-age值來進行判斷,它是一個相對值;資源第一次的請求時間和Cache-Control設定的有效期,計算出一個資源過期時間,再拿這個過期時間跟當前的請求時間比較,如果請求時間在過期時間之前,就能命中緩存,否則就不行;
- cache-control常用的值(做一個簡單了解即可):
- no-cache: 不使用本地緩存,需要使用協商緩存。先與服務器確認返回的響應是否被更改,如果之前的響應中存在Etag,那么請求的額時候會與服務器端進行驗證,如果資源為被更改則使用緩存。
- no-store: 直接禁止游覽器緩存數據,每次用戶請求該資源,都會向服務器發送一個請求,每次都會下載完整的資源。
- public:可以被所有的用戶緩存,包括終端用戶和CDN等中間代理服務器。
- private:只能被終端用戶的瀏覽器緩存,不允許CDN等中繼緩存服務器對其緩存。
- 注意:當cache-control與Expires共存的時候cache-control的優先級高
協商緩存的header參數
重點:協商緩存都是由服務器來確定緩存資源是否可用的,所以客戶端與服務器端要通過某種標識來進行通信,從而讓服務器判斷請求資源是否可以緩存訪問
- Last-Modified/If-Modified-Since:二者的值都是GMT格式的時間字符串
- 瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在respone的header加上Last-Modified的header,這個header表示這個資源在服務器上的最后修改時間
- 瀏覽器再次跟服務器請求這個資源時,在request的header上加上If-Modified-Since的header,這個header的值就是上一次請求時返回的Last-Modified的值
- 服務器再次收到資源請求時,根據瀏覽器傳過來If-Modified-Since和資源在服務器上的最后修改時間判斷資源是否有變化,如果沒有變化則返回304 Not Modified,但是不會返回資源內容;如果有變化,就正常返回資源內容。當服務器返回304 Not Modified的響應時,response header中不會再添加Last-Modified的header,因為既然資源沒有變化,那么Last-Modified也就不會改變,這是服務器返回304時的response header
- 瀏覽器收到304的響應后,就會從緩存中加載資源
- 如果協商緩存沒有命中,瀏覽器直接從服務器加載資源時,Last-Modified的Header在重新加載的時候會被更新,下次請求時,If-Modified-Since會啟用上次返回的Last-Modified值
- 圖例:
-
Etag/If-None-Match
- 這兩個值是由服務器生成的每個資源的唯一標識字符串,只要資源有變化就這個值就會改變
- 其判斷過程與Last-Modified/If-Modified-Since類似
-
既生Last-Modified何生Etag
- HTTP1.1中Etag的出現主要是為了解決幾個Last-Modified比較難解決的問題
- 一些文件也許會周期性的更改,但是他的內容并不改變(僅僅改變的修改時間),這個時候我們并不希望客戶端認為這個文件被修改了,而重新GET
- 某些文件修改非常頻繁,比如在秒以下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改無法判斷(或者說UNIX記錄MTIME只能精確到秒);
- 某些服務器不能精確的得到文件的最后修改時間。
小結:
利用Etag能夠更加準確的控制緩存,因為Etag是服務器自動生成或者由開發者生成的對應資源在服務器端的唯一標識符。
Last-Modified與ETag是可以一起使用的,服務器會優先驗證ETag,一致的情況下,才會繼續比對Last-Modified,最后才決定是否返回304。