日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

什么是前端缓存

發布時間:2023/12/20 HTML 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 什么是前端缓存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家在日常的開發工作過程中,有沒有遇到過下面幾種情況:

  • 部署/發布前端工程后,增加的功能或修改的bug沒有生效
  • 測試同學測試功能時經常暴力地清除所有瀏覽器緩存
  • 前端開發同學經常說:你“強刷”一下就好了

遇到上面這些情況,大部分同學就知道了,這是前端有緩存的原因,那具體什么是前端緩存呢,前端緩存僅僅和前端有關系嗎?

前端緩存 / 瀏覽器緩存

前端緩存,是瀏覽器為了提升網站的加載性能,縮短用戶等待時間而采取的措施,瀏覽器總是想盡量少地向服務器發送請求,能夠從自己保存的副本中得到的,就不去麻煩服務器了,畢竟自己動手豐衣足食嘛,所以更準確的叫法應該為瀏覽器緩存,下文中如果出現緩存等字眼,指的就是前端緩存或瀏覽器緩存。

由上所述,緩存對于用戶來說是友好的,而且對大多數用戶透明的,普通用戶可能最多只是感覺再次進入一個網站時速度變快了而已,再進一步可能某些用戶發現一些靜態頁面斷網后還能被訪問。但是對于開發同學就需要對緩存有所了解,并在發布新版時特別注意。

緩存機制

那緩存是具體是什么呢?我們可以將其理解為我們下載到硬盤的文件,比如說老師為我們制作了一份課件,我們將其下載放在了硬盤中,那之后我們什么時候想看,只需要到這份課件保存的文件夾內,將其打開就好了,而不必再次下載了。但是有一天老師發現了課件里面有一些問題,那老師為了不誤導我們肯定想要修正這些問題,修正過后呢,老師在上課的時候就告訴我們“同學們,你們上次下載的課件有些問題,我已經改了,你們再重新下載一下,之前那份就不要看了”。那我們回去之后就重新下載老師修改過后的課件,之前的課件就再也不需要看了。

明白了上面的例子,其實也就明白了緩存的機制,對應于緩存,工作流程應該是這樣的:

用戶小U使用瀏覽器小B訪問了一個頁面P,瀏覽器將頁面P和其中包含的資源文件(一般包含css、js、圖片等文件)保存下來了,一段時間內呢小B反復訪問頁面P,小B都會從自己的存儲區取出相應文件為小U渲染出同樣的頁面P。然后有一天頁面P更新了,比如說主題變了或者里面的按鈕功能變化了,當小B再次訪問頁面P時,它知道自己之前保存的頁面P的資源文件已經過時了,然后就再次訪問一下頁面P,再將頁面P和其中包含的資源文件保存下來,之前保存的頁面P和其中包含的資源文件就沒用了。

那上面兩個流程是不是都有個重新下載的過程,那重要的就是如果感知到資源的變化。第一個例子中是老師通知同學們資源變化了,第二個例子就沒有上面說的那么簡單了,沒人主動告訴小B它緩存的資源已經過時了,那小B是通過什么方式才能知道自己緩存的資源已經過時了呢:

緩存的狀態

狀態備注
無緩存初次見面,第一次進入某個頁面
緩存過時/非法重逢不識君,進入過某個頁面,并有對應緩存,但再次進入時可能已經過時了
緩存合法歸來仍是少年,進入過某個頁面,并有對應緩存,再次進入時仍然是有效的

而緩存狀態的變化,需要瀏覽器和服務器之間達成某些協議,這些協議由HTTP頭部確定及執行,這里我們介紹最常用的:

緩存頭部

  • Cache-Control
  • Etag及If-None-Match夫婦
  • Last-Modified及If-Modified-Since夫婦

Cache-Control

Cache-Control的語法及使用姿勢眾多,剛興趣的可直接到MDN查看,這里我們只介紹它在響應頭中用于告知瀏覽器如何進行緩存行為:

Response HeadersCache-Control: public, max-age=31536000

上面的響應頭中Cache-Control: public, max-age=31536000告知瀏覽器從當前請求的時間點開始,再次請求此資源如果還未超過31536000秒(1年),你就就不必問我了,放心地使用你本地保存的就好了。但是這就有個問題了,如果一年內的某天,此資源變化了,瀏覽器該如何知道呢?很遺憾,這種情況下瀏覽器在1年內是不會再知道了。

所以如果web server想要對資源設置諸如Cache-Control: public, max-age=31536000響應頭,一般需要前端搭配文件名hash來使用,這在各種構建工具或腳手架中一般都有相應的配置,如webpack配置:

// webpack module.exports = {// ...output: {filename: '[name].[contenthash].js',// filename: '[name].[hash].js',// ...},optimization: {moduleIds: 'hashed',// ...},// ... }

適用資源:基本所有的資源型文件(如js、css、圖片、字體文件等)。

設置為1年沒有什么其他含義,只是一個較大的時間區間而已。


當我們按照上面方式配置完成后,滿心歡喜的去發布新版了,可是部署完成后再次訪問,尷尬了,沒有變化?這就要注意了,緩存對于html文件也是生效的,我知道這很顯而易見,但是很多人容易忽略。

特別是對于單頁面應用來說,我們一般只有一個index.html,在index.html中引入其他js、css等資源文件,上面的步驟只是對于index.html中引入的資源文件名中添加了hash,保證發布新版后這些引入的資源文件在瀏覽器緩存中不存在,但是如果瀏覽器取得index.html是通過本地緩存得到的呢?

<!-- 緩存內index.html --> <link rel="stylesheet" href="index.v1.css" /> <script src="index.v1.js"></script> <!-- 新版的index.html --> <link rel="stylesheet" href="index.v2.css" /> <script src="index.v2.js"></script>

這里為了方便,我們使用v1、v2等代指hash。

很顯然,如果瀏覽器從緩存中獲取index.html,然后肯定會嘗試獲取index.v1.css和index.v1.js,而這兩個文件再緩存中也是存在的且是合法的(假設還在1年內),那自然用戶看到的頁面及功能都是老的了。那我們應該如何為html文件設置緩存策略呢?

我們可以在web server的配置中針對html文件設置Cache-Control: no-cache,當我們請求html文件時,響應頭會包含:

Response HeadersCache-Control: no-cache

要特別注意no-cache(允許緩存,但是使用前要向服務器確定緩存是否合法,確定方案下面會講到)和no-store(不允許緩存)的區別。

這樣的話,當我們發布新版后,瀏覽器請求index.html發現有緩存,但并不會無腦的使用,而是會向服務器確認一下當前的緩存是否合法,如果合法則直接使用緩存內的版本,否則會向服務器請求最新的index.html,之后我們的index.v2.css和index.v2.js就能夠被正確獲取,用戶就能夠看到新的頁面了。

ETag及If-None-Match

ETag被稱為實體標簽或版本標識符,ETag變化代表資源的變化。

上面說道,瀏覽器有時需要向服務器確定緩存是否合法,那通過ETag響應頭部和If-None-Match請求頭部就能夠確定,大致過程如下:

  • 首次請求index.html,服務器響應頭部中包含ETag: W/"v1"首部
  • 瀏覽器緩存index.html,再次請求index.html時,請求頭部包含If-None-Match: W/"v1"
  • 服務器確定index.html是否有變化,如果沒有變化,則狀態碼返回304,并且沒有響應體,瀏覽器將使用本地緩存;如果有變化,則狀態碼返回200,將新的index.html傳給瀏覽器,并返回新的ETag: W/"v2"首部
  • 重復2、3
  • v1、v2只是為了標識出ETag的變化,實際上生成ETag的算法也不唯一,甚至簡單地使用版本號也可以。關于ETag詳細信息可參閱MDN。

    Last-Modified及If-Modified-Since

    除了ETag及If-None-Match,使用Last-Modified和If-Modified-Since組合也能起到類似的效果,大致過程和前組合類似:

  • 首次請求index.html,服務器響應頭部中包含Last-Modified: Wed, 21 Oct 2019 07:28:00 GMT首部
  • 瀏覽器緩存index.html,再次請求index.html時,請求頭部包含If-Modified-Since: Wed, 21 Oct 2019 07:28:00 GMT
  • 服務器確定index.html是否有變化(通過資源的最近修改時間和Wed, 21 Oct 2019 07:28:00 GMT對比),如果沒有變化,則狀態碼返回304,并且沒有響應體,瀏覽器將使用本地緩存;如果有變化,則狀態碼返回200,將新的index.html傳給瀏覽器,并返回新的Last-Modified: Wed, 22 Oct 2019 09:32:00 GMT首部
  • 重復2、3
  • Last-Modified和If-Modified-Since組合準確度不如ETag及If-None-Match組合,所以不太推薦使用:

    • 有些服務器無法正確地判斷資源的最近修改日期
    • 如果資源的變化周期在秒級以下,只能精確到秒的修改日期就不那么精確了

    確定緩存是否合法,也會發請求和服務器端通信,但如果緩存有效,服務器發回的響應中是不包含響應體的,這樣流量消耗是很小的,只有頭部的消耗;即使緩存無效,也只是相當于發了一個首次請求而已。

    總結

    綜上所述,我們可以在部署前端工程時使用如下方案,保證用戶能夠享受緩存帶來的便利,也能保證不會因為緩存造成更新不生效的問題:

    • 針對大部分資源文件,使用Cache-Control: public, max-age=31536000及文件名hash的方案
    • 針對html文件,使用Cache-Control: no-cache和ETag方案

    為不同類型資源配置響應頭部是web server的工作,請求頭部是瀏覽器的自發工作,文件hash是前端的工作。

    總結

    以上是生活随笔為你收集整理的什么是前端缓存的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。