瀏覽器快取分為兩種型別:
瀏覽器快取機制的過程如下:
強快取是最徹底的快取,無需向伺服器傳送請求,通常用於css、js、等靜態資源。瀏覽器傳送請求後會先判斷本地是否有快取。如果無快取,則直接向伺服器傳送請求;如果有快取,則判斷快取是否命中強快取,如果命中則直接使用本地快取,如果沒命中則向伺服器傳送請求。判斷是否命中本地快取的方法有兩種:expires和cache-control。
expires是http1.0的響應頭,代表的含義是資源本地快取的過期時間,由伺服器設定。伺服器返回給瀏覽器的響應頭中如果包含expires欄位,瀏覽器傳送請求時拿當前時間和expires字段值進行比較,判斷資源快取是否失效。如下圖所示:
date代表請求資源的時間,expires代表資源快取的過期時間,可以看到伺服器設定資源的快取時間為5分鐘。2017-02-10 07:53:19之前,請求這個資源就是命中本地快取。超過這個時間再去請求則不命中。
cache-control是http1.0中新增的字段。由於expires設定的是資源的具體過期時間,如果伺服器時間和客戶端時間不一樣,就會造成快取錯亂,比如認為調節了客戶端的時間,所以設定資源有效期的時長更合理。http1.1新增了cache-control的max-age欄位。max-age代表的含義是資源有效期的時長,是乙個相對時長,單位為s。
cache-control: max-age = 300設定資源的過期時間為5分鐘。瀏覽器再次傳送請求時,會把第一次請求的時間和max-age字段值相加和當前時間比較,以此判斷是否命中本地快取。max-age使用的都是客戶端時間,比expires更可靠。如果max-age和expires同時出現,max-age的優先順序更高。cache-control提供了更多的字段來控制快取:
協商快取的判斷在伺服器端進行,判斷是否命中的依據就是這次請求和上次請求之間資源是否發生改變。未發生改變命中,發生改變則未命中。判斷檔案是否發生改變的方法有兩個:last-modified、if-modified-since和etag、if-none-match。
last-modified是http1.0中的響應頭欄位,代表請求的資源最後一次的改變時間。if-modified-since是http1.0的請求頭,if-modified-since的值是上次請求伺服器返回的last-modified的值。瀏覽器第一次請求資源時,伺服器返回last-modified,瀏覽器快取該值。瀏覽器第二次請求資源時,用於快取的last-modified賦值給if-modified-since,傳送給伺服器。伺服器判斷if-modified-since和伺服器本地的last-modified是否相等。如果相等,說明資源未發生改變,命中協商快取;如果不相等,說明資源發生改變,未命中協商快取。
可以看到該請求返回的是304狀態碼,說明資源的last-modified未改變,所以這次請求的last-modified和if-modified-since是一致的。
last-modified、if-modified-since使用的都是伺服器提供的時間,所以相對來說還是很可靠的。但是由於修改時間的精確級別或者定期生成檔案這種情況,會造成一定的錯誤。所以http1.1新增etag、if-none-match欄位,完善協商快取的判斷。etag是根據資源檔案內容生成的資源唯一識別符號,一旦資源內容發生改變,etag就會發生改變。基於內容的識別符號比基於修改時間的更可靠。if-none-match的值是上次請求伺服器返回的etag的值。etag、if-none-match的判斷過程和last-modified、if-modified-since一致,etag、if-none-match的優先順序更高。
如何使強快取失效,是問題的關鍵。通常的解決方法是更新檔名,檔名不一樣的話,瀏覽器就會重新請求資源。我們要保證新發布版本和不同環境中的檔名是不一樣的。其中一種方法在檔名後加版本號:
index.js?version=1
index.css?version=1
複製**
webpack提供了很簡單的方法可以配置快取。
// webpack.config.js
module.exports =
};複製**
通過hash佔位符,在每次生成打包檔案時,都會通過檔案內容生成唯一的hash,並新增到輸出的檔名中。如果有多個入口檔案,可以使用name佔位符設定輸出:
// webpack.config.js
module.exports = ,
output:
};複製**
這時候有乙個問題是,此時的hash是根據兩個檔案的內容來生成的,兩個檔名使用的hash是一致的。如果main.js和sub.js只有乙個改變,兩個檔名都會改變,兩個檔案都會重新請求,造成資源浪費。webpack提供了chunkhash來代替hash在多入口情況下使用。chunkhash是根據每個入口檔案單獨生成的雜湊值,避免上述情況。
webpack打包動態生成檔名,我們需要動態地把檔案引用插入到html啟動檔案中。html-webpack-plugin可以幫我很好地解決這個問題。html-webpack-plugin
可以動態地生成乙個html檔案,並在html檔案中動態插入webpack打包生成的資源檔案。
var htmlwebpackplugin = require('html-webpack-plugin');
var webpackconfig = ,
plugins: [new htmlwebpackplugin()]
};複製**
預設在webpackconfig.output.path
路徑下生成index.html
,生成的html檔案如下:
charset="utf-8">
head>
src="main.2a6c1fee4b5b0d2c9285.js">
script>
body>
html>
複製**
通常html啟動檔案都有自定義的內容,所以html-webpack-plugin
提供了模板功能,template欄位設定模板的路徑,html-webpack-plugin
以template為模板,動態新增webpack打包生成的資源路徑。
var htmlwebpackplugin = require('html-webpack-plugin');
var webpackconfig = ,
plugins: [new htmlwebpackplugin(
)]};複製**
原index.html內容(\index.html):
lang="en">
charset="utf-8">
stat-fronttitle>
rel="stylesheet"
href="">
head>
router-view>
div>
body>
html>
複製**
生成的index.html內容(\dist\index.html):
lang="en">
charset="utf-8">
stat-fronttitle>
rel="stylesheet"
href="">
head>
router-view>
div>
src="main.2a6c1fee4b5b0d2c9285.js">
script>
body>
html>
複製**
最開始的時候靜態的index.html在根目錄下,webpack-dev-server
設定的啟動路徑就是根目錄下的index.html,如果要啟動生成的index.html,還需要設定webpackconfig.output.publicpath
:
var htmlwebpackplugin = require('html-webpack-plugin');
var webpackconfig = ,
plugins: [new htmlwebpackplugin(
)]};複製**
這樣webpack-dev-server在記憶體中生成的資源都存放在根目錄下,生成的index.html會代替原index.html啟動。
部落格位址
瀏覽器快取和webpack快取配置
網路請求會耗費大量時間和請求,如果可以重用為改變的網路資源,對於使用者來說可以更快更流暢的檢視網頁,對於伺服器來說減少了很多負荷,所以瀏覽器快取是前端優化的重要內容。本文介紹了瀏覽器快取的機制和快取在webpack中的應用。瀏覽器快取分為兩種型別 瀏覽器快取機制的過程如下 強快取是最徹底的快取,無需...
webpack 與 瀏覽器快取
我們先在專案中加入 jquery 與 lodash 庫。然後在index.js 中引入並使用,如下。import from lodash import from jquery const dom dom.html join hello world 然後打包。這裡我們先把sourcemap 檔案去掉,...
快取 瀏覽器快取
瀏覽器快取 brower caching 是瀏覽器在本地磁碟對使用者最近請求過的文件進行儲存,當訪問者再次訪問同一頁面時,瀏覽器就可以直接從本地磁碟載入文件 1 瀏覽器第一次請求時,會發出一組 http 頭,用來指導瀏覽器如何進行快取。伺服器規定乙個資源是否要進行快取,主要由響應頭中的expires...