簡(jiǎn)單聊一下瀏覽器緩存

前言

在前端開(kāi)發(fā)中,網(wǎng)站性能是非常重要的一點(diǎn),一個(gè)優(yōu)秀的緩存策略能夠減少帶寬,降低網(wǎng)絡(luò)負(fù)荷,減少延遲。本文簡(jiǎn)單聊一下瀏覽器緩存。

緩存分類

Web緩存分為多種, 如數(shù)據(jù)庫(kù)緩存、DNS緩存、CDN緩存,以及瀏覽器緩存等。

瀏覽器緩存

一、什么是瀏覽器緩存?


簡(jiǎn)單一點(diǎn)說(shuō),瀏覽器緩存就是將通過(guò)HTTP請(qǐng)求獲取的資源保存在本地的一種行為。

二、緩存位置

  • memory cache
  • disk cache

三、三級(jí)緩存原理 (訪問(wèn)緩存優(yōu)先級(jí))

  1. 先在內(nèi)存中查找,如果有,直接加載。
  2. 如果內(nèi)存中不存在,則在硬盤中查找,如果有直接加載。
  3. 如果硬盤中也沒(méi)有,那么就進(jìn)行網(wǎng)絡(luò)請(qǐng)求。
  4. 請(qǐng)求獲取的資源緩存到硬盤和內(nèi)存。

四、瀏覽器緩存的分類

  • 強(qiáng)緩存
    瀏覽器在加載資源時(shí),會(huì)先根據(jù)本地緩存資源的 header 中的信息判斷是否命中強(qiáng)緩存,如果命中則直接使用緩存中的資源不會(huì)再向服務(wù)器發(fā)送請(qǐng)求。在chrome控制臺(tái)的Network選項(xiàng)中可以看到該請(qǐng)求返回200的狀態(tài)碼,并且Size顯示from disk cache或from memory cache。強(qiáng)緩存可以通過(guò)設(shè)置兩種 HTTP Header 實(shí)現(xiàn):Expires 和 Cache-Control。

  • 協(xié)商緩存
    當(dāng)強(qiáng)緩存沒(méi)有命中的時(shí)候,瀏覽器會(huì)發(fā)送一個(gè)請(qǐng)求到服務(wù)器,服務(wù)器根據(jù) header 中的部分信息來(lái)判斷是否命中緩存。如果命中,則返回 304 ,告訴瀏覽器資源未更新,可使用本地的緩存。這里的 header 中的信息指的是 Last-Modify/If-Modify-Since 和 ETag/If-None-Match。

緩存機(jī)制

強(qiáng)制緩存優(yōu)先于協(xié)商緩存進(jìn)行,若強(qiáng)制緩存(Expires和Cache-Control)生效則直接使用緩存,若不生效則進(jìn)行協(xié)商緩存(Last-Modified / If-Modified-Since和Etag / If-None-Match),協(xié)商緩存由服務(wù)器決定是否使用緩存,若協(xié)商緩存失效,那么代表該請(qǐng)求的緩存失效,返回200,重新返回資源和緩存標(biāo)識(shí),再存入瀏覽器緩存中;生效則返回304,繼續(xù)使用緩存。具體流程如下。

實(shí)踐

一、搭建服務(wù)

這里用Egg.js 框架起一個(gè)WEB服務(wù)器(是阿里開(kāi)源的基于Koa2的企業(yè)級(jí) Node.js 框架)。
對(duì)強(qiáng)緩存的Cache-Control和協(xié)商緩存的Etag 進(jìn)行測(cè)試。

  1. 項(xiàng)目初始化
$ npm i egg-init -g
$ egg-init egg-web --type=simple
$ cd egg-web
$ npm i
  1. 編寫(xiě) Controller
// app/controller/cache.js
const Controller = require('egg').Controller
class CacheController extends Controller {
    async cache() {
        await this.ctx.render('cache/index.tpl')
    }
}

module.exports = CacheController
  1. 配置路由映射
//app/router.js
module.exports = app => {
    const {router, controller} = app
    router.get('/cache', controller.cache.cache)
}
  1. 靜態(tài)資源

Egg 內(nèi)置了 static 插件,線上環(huán)境建議部署到 CDN,無(wú)需該插件。static 插件默認(rèn)映射 /public/* -> app/public/* 目錄
此處,我們把靜態(tài)資源都放到 app/public 目錄即可:

app/public
├── css
│   └── cache.css
└── img
    ├── flow.png
    └── ppd.png
  1. 模板渲染
// app/view/cache/index.tpl
<html>
  <head>
    <title>前端緩存</title>
    <link rel="stylesheet" href="/public/css/cache.css" />
    <meta name="viewport" content="width=device-width, initial-scale=1, 
          maximum-scale=1, minimum-scale=1, user-scalable=no">
  </head>
  <body>
  <div class = "content">
   <h3>Front-end cache testing</h3>
   <img src="/public/img/ppd.png"/>
  </div>
  </body>
</html>

6.啟動(dòng)服務(wù)

$ npm run dev

輸入地址

http://127.0.0.1:7001/cache

二、強(qiáng)緩存和協(xié)商緩存實(shí)踐

主要演示下cacheControl與ETag設(shè)置的效果

//  config/config.default.js
const path = require('path');
module.exports = (appInfo) => {
    const config = exports = {};
    ...
   config.static = {
        prefix: '/public/',
        dir: path.join(appInfo.baseDir, 'app/public'),
        cacheControl: 'max-age=600'
    }
    ....
    return config;
};

此時(shí),瀏覽器把ppd.png圖片緩存到了磁盤和內(nèi)存中,刷新頁(yè)面后會(huì)先在內(nèi)存中找到資源,如下圖所示:


關(guān)閉Tab頁(yè)面,由于內(nèi)存是存在進(jìn)程中的,關(guān)閉頁(yè)面,內(nèi)存中的資源被釋放掉,磁盤中的資源是永久性的,所以還存在。根據(jù)三級(jí)緩存原理,重新打開(kāi)頁(yè)面,便會(huì)在磁盤中找到資源。

剛剛對(duì)資源的有效期設(shè)置的是600秒,600秒后重新刷新頁(yè)面,可以清楚的看到,強(qiáng)緩存失效了,并命中了協(xié)商緩存。如下圖所示。

egg-static靜態(tài)服插件,基礎(chǔ)與koa的靜態(tài)插件 koa-static-cache.Uses MD5 hash sum as an ETag.

驗(yàn)證服務(wù)器端資源變化時(shí),協(xié)商緩存是否失效,修改ppd.png,刷新頁(yè)面,此時(shí),消息頭結(jié)果如下:

Gerneral
     Status Code: 200 OK
Response Headers
     ETag:"vSoLmwZqMEbQmnfRGN3p/w=="
Request Headers
     If-None-Match:"+xVGjRSF2PfxkkUeQPrJyQ=="

可以看出, If-None-Match !== ETag,協(xié)商緩存失效,瀏覽器重新向服務(wù)器發(fā)起請(qǐng)求。

結(jié)語(yǔ)

本文簡(jiǎn)單介紹了下瀏覽器的緩存,希望對(duì)大家有點(diǎn)小的幫助,限于篇幅,每一部分的描述都比較簡(jiǎn)略,僅起到拋磚引玉之用。如有錯(cuò)誤,還望指出。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容