過程:javascript
不會向服務器發送請求,直接從緩存中讀取資源,
在chrome控制檯的network選項中能夠看到該請求返回200的狀態碼,
而且size顯示from disk cache或from memory cache;
複製代碼
設置強制緩存的方式:
在響應頭設置:
Catch-Control優先級 > Expires優先級
Catch-Control:
好比Cache-Control:max-age=300(秒)
表明在這個請求正確返回時間(瀏覽器也會記錄下來)的5分鐘內再次加載資源,就會命中強緩存
Expires:
好比Expires:Thu,21 Jan 2020 23:39:02 GMT
response header裏的過時時間,瀏覽器再次加載資源時,若是在這個過時時間內,則命中強緩存。
它的值爲一個絕對時間的GMT格式的時間字符串;
存在一個缺點:但因爲服務端時間和客戶端時間可能有偏差,這也將致使緩存命中的偏差,所以如今經常使用這個;
複製代碼
協商緩存:向服務器發送請求,服務器會根據這個請求的request
header的一些參數來判斷是否命中協商緩存,若是命中,則返回304狀態碼並帶上新的response
header通知瀏覽器從緩存中讀取資源;另外協商緩存須要與cache-control共同使用。;
複製代碼
設置協商緩存的方式:
在響應頭設置:
Etag優先級 > Last-Modified優先級
Etag:
服務器響應請求時,經過此字段告訴瀏覽器當前資源在服務器生成的惟一標識(生成規則由服務器決定);
If-None-Match: 再次請求服務器時,瀏覽器的請求報文頭部會包含此字段,後面的值爲在緩存中獲取的標識。
服務器接收到次報文後發現If-None-Match則與被請求資源的惟一標識進行對比:
a. 不一樣,說明資源被改動過,則響應整個資源內容,返回狀態碼200。
b. 相同,說明資源無意修改,則響應header,瀏覽器直接從緩存中獲取數據信息。返回狀態碼304.
c. 可是實際應用中因爲Etag的計算是使用算法來得出的,而算法會佔用服務端計算的資源,
全部服務端的資源都是寶貴的,因此就不多使用Etag了。
Last-Modified: Fri, 22 Jul 2020 01:47:00 GMT
服務器在響應請求時,會告訴瀏覽器資源的最後修改時間;
if-Modified-Since:
瀏覽器再次請求服務器的時候,請求頭會包含此字段,後面跟着在緩存中得到的最後修改時間。
服務端收到此請求頭髮現有if-Modified-Since,則與被請求資源的最後修改時間進行對比,
若是一致則返回304和響應報文頭,瀏覽器只須要從緩存中獲取信息便可。
從字面上看,就是說:從某個時間節點算起,是否文件被修改了:
a. 若是真的被修改:那麼開始傳輸響應一個總體,服務器返回:200 OK
b. 若是沒有被修改:那麼只需傳輸響應header,服務器返回:304 Not Modified
if-Unmodified-Since:
從字面上看, 就是說: 從某個時間點算起, 是否文件沒有被修改
若是沒有被修改:則開始繼續傳送文件: 服務器返回: 200 OK
若是文件被修改:則不傳輸,服務器返回: 412 Precondition failed (預處理錯誤);
這兩個的區別是一個是修改了才下載一個是沒修改才下載。
Last-Modified 說好卻也不是特別好,由於若是在服務器上,一個資源被修改了,但其實際內容根本沒發生改變,
會由於Last-Modified時間匹配不上而返回了整個實體給客戶端(即便客戶端緩存裏有個如出一轍的資源)。
爲了解決這個問題,HTTP1.1推出了Etag。
複製代碼
強制緩存優先級 > 協商緩存優先級;css
刷新html
用戶行爲對瀏覽器緩存的影響
1.地址欄訪問,連接跳轉是正經常使用戶行爲,將會觸發瀏覽器緩存機制;
2.F5刷新,瀏覽器會設置max-age=0,跳過強緩存判斷,會進行協商緩存判斷;
3.ctrl+F5刷新,跳過強緩存和協商緩存,直接從服務器拉取資源。
複製代碼
a. 減小了冗餘的數據傳遞,節省寬帶流量
b. 減小了服務器的負擔,大大提升了網站性能
c. 加快了客戶端加載網頁的速度 這也正是HTTP緩存屬於客戶端緩存的緣由。
複製代碼
<script src="test.js" type="text/javascript" defer></script>
複製代碼
function loadScript(url, callback) {
const script = document.createElement('script');
script.type = 'text/javascript';
// 處理IE
if (script.readyState) {
script.onreadystatechange = function () {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
script.onreadystatechange = null;
callback();
}
}
} else {
// 處理其餘瀏覽器的狀況
script.onload = function () {
callback();
}
}
script.src = url;
document.body.append(script);
}
// 動態加載js
loadScript('file.js', function () {
console.log('加載完成');
});
複製代碼
// 優化前
const el = document.getElementById('test');
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';
// 優化後,一次性修改樣式,這樣能夠將三次重排減小到一次重排
const el = document.getElementById('test');
el.style.cssText += '; border-left: 1px ;border-right: 2px; padding: 5px;'
複製代碼
let arr1 = [{id: 12, name: 'aa'}, {id: 33, name: 'aa'}];// => {12: {id: 12, name: 'aa', 33: {id: 12, name: 'aa'}};
let arr2 = [{id: 12, age: '18'}, {id: 33,age: '22' }];
複製代碼