一看就懂的浏览器缓存

一看就懂的浏览器缓存

什么是浏览器缓存?

​ 浏览器缓存其实就是,浏览器把通过请求的网络资源存储在本地的一种行为。

为什么需要浏览器缓存?

  1. 可以加速资源的下载速度,提升页面加载速度

  2. 减小服务器的压力

浏览器缓存的资源去哪里了呢?

  1. Memory cache:这个表示存储在内存中,等下次获取的时候就不用重新下载,而是直接从内存里面获取,由于这种存储方式在进程退出后资源会被删除,所以一般用于存储一些脚本文件,或者外连的一些图片资源

  2. Disk cache:这个表示存储在磁盘中,等下次获取的时候就不用重新下载,而是直接从电脑磁盘里面获取,由于这种存储方式在进程退出后资源也不会被删除,所以一般用于存储不经常改变的资源,比如:css

浏览器缓存的类别?

  1. 强缓存

  2. 协商缓存

浏览器在请求资源的时候,缓存类别判断顺序-------->会先判断是否命中强缓存,在判断是否命中协商缓存。

  1. 强缓存

    是否命中强缓存的规则是查看资源header信息里面的字段expires和cache-control

http版本取值是否可靠
Expires1.0取值是一个绝对时间,比如Expires::Sun,18 Oct 2021 23:59:59 GMT,表示在这个时间之内资源都是会命中强缓存的不可靠(由于服务器和浏览器之间可能会有时间差)
Cache-Control1.1取值有:no-cache/no-store/max-age/private/public。
no-cache:表示的是不使用强缓存,使用协商缓存;
no-store:表示不使用缓存,每一次都从服务器拉取资源;
max-age:表示一个相对的资源过期时间,比如Cache-Control:max-age=300,表示资源的有效时间是300秒;
private:表示资源是私有的,只能被终端用户缓存,禁止被中间代理服务器;
public:表示资源是共有的,可以被所有用户缓存(包含中间代理服务器)
可靠
  1. 协商缓存

    当没有命中强缓存的时候,浏览器就会发送一个http请求到服务端,服务端根据header里面的一些信息判断是否命中协商缓存,其中判断规则如下:

字段含义判定规则判定结果优缺点
Last-Modify/If-Modify-SinceLast-Modify:指的是服务器资源最后一次修改的时间;
If-Modify-Since:指的是再次发起请求时候request-header里面携带的上一次response-header里面的Last-Modify的值
比如
第一次请求接口get-user-info的时候response-header里面Last-Modify:115556,
下一次请求接口get-user-info时候request-header里面就会携带If-Modify-Since:115556,然后服务端接受到这个If-Modify-Since:115556之后就会去对比是否与现在的Last-Modify时间一致
时间一致:表示命中缓存,资源没有跟新,返回304,表示从浏览器缓存读取资源
时间不一致:表示资源更新了,这个时候就会从服务端拉取最新的资源
1. 如果服务器的资源短时间的变化,Last-Modified 并不会发生变化
2.周期性的变化(比如资源A变成B,最后又变回A),按逻辑是可以使用缓存的,但是Last-Modified 实际上是发生改变的
ETag/If-None-MatchETag:指的是服务器资源所对应的唯一校验码,相当于资源的一个身份证;
If-None-Match:指的是再次发起请求时候request-header里面携带的上一次response-header里面的ETag的校验码的值
比如
第一次请求接口get-user-info时候response-header里面ETag:510322,
下一次请求接口get-user-info时候request-header里面就会携带If-None-Match:510322,然后服务端接受到这个If-None-Match:510322之后就会去对比是否与现在的ETag校验码一致
校验码一致:表示命中缓存,资源没有更新,返回304,表示从浏览器缓存读取资源
校验码不一致:表示资源更新了,这个时候就会从服务端拉取最新的资源
由于校验码是每一个服务器资源的唯一标志,所以不管是短时间的资源改变,还是周期性改变,只要是相同的资源就会是相同的Etag,不同的资源就会是不同的Etag,因此就不会出现Last-Modify/If-Modify-Since上面那种特殊情况
总结:

在这里插入图片描述

相信光看一些文字大家理解起来肯定还是不那么直观,所以下面我用demo的方法,实际操作一下,加深一下对上述概念的理解

Demo

文件目录大致如下:

在这里插入图片描述

  1. 强缓存demo

核心代码如下:

package.json

{
  "name": "caches",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "server": "nodemon ./index.js"
  },
  "author": "ymx",
  "license": "MIT",
  "devDependencies": {
    "koa": "^2.6.2",
    "koa-conditional-get": "^2.0.0",
    "koa-etag": "^3.0.0",
    "koa-static": "^5.0.0"
  },
  "dependencies": {
    "nodemon": "^1.18.9"
  }
}

index.js

require('./server.js');

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>浏览器缓存</title>
    <link rel="stylesheet" href="./index.css">
</head>
<style>
</style>
<body>
    <img class="img-style" src="./test1.jpeg" alt="">
</body>
</html>

index.css

.img-style{
    width: 100%;
}

server.js

const Koa = require('koa');
const path = require('path');
const statics = require('koa-static');
const app = new Koa();
const port = 8888;

app.use(async (ctx, next) => {
 // 设置响应头Cache-Control 设置资源有效期为100秒
  ctx.set({
    'Cache-Control': 'max-age=100'  
  });
  await next();
});
app.use(statics(path.resolve(__dirname, './static')));
app.listen(port, () => {
  console.log(`服务器启动在${port}端口`);
});

一切准备工作就绪,就等启动服务

npm run server   
// 服务器启动在8888端口

然后我们在浏览器输入locahost:8888回车,见证奇迹😂

在这里插入图片描述
由请求我们可以发现,请求头里面多了Cache-Control:max-age=100这一条信息,表示这个资源的过期时间是100s

由于在第一次请求资源之后,图片test1.jpeg实际上已经被存储在内存和磁盘里面。

所以,当我们再100s之内刷新页面,会发现Status Code: 200 OK (from memory cache),表示这个时候是从内存中读取的图片资源

在这里插入图片描述
接着我们关闭浏览器页面,然后重新locahost:8888打开,会发现Status Code: 200 OK (from disk cache),表示这个时候是从磁盘中读取的图片资源

在这里插入图片描述
然后等100s之后再次刷新页面,发现Status Code: 200 OK,表示缓存时间失效,需要从服务器重新拉取资源

在这里插入图片描述
总结:强缓存遵寻三级缓存策略------->在找寻资源的时候,如果在内存中找到资源就从内存中拉取,没找到才去磁盘中找

  1. 协商缓存

目录结构都一样,唯一不一样的就是server.js文件

安装一些自动生成Etag的插件

yarn add koa-tag
yarn add koa-conditional-get

改变一下Cache-Control为走协商缓存

'Cache-Control': 'no-cache'  

server.js

const Koa = require('koa');
const path = require('path');
const statics = require('koa-static');
//静态资源中间件
const conditional = require('koa-conditional-get');
const etag = require('koa-etag');
const app = new Koa();
const port = 8888;

app.use(conditional());
app.use(etag());
app.use(async (ctx, next) => {
 // 设置响应头Cache-Control:'no-cache'
  ctx.set({
    'Cache-Control': 'no-cache'  
  });
  await next();
});
app.use(statics(path.resolve(__dirname, './static')));

app.listen(port, () => {
  console.log(`服务器启动在${port}端口`);
});

第一次请求:Status Code: 200 OKresponse返回了EtagLast-Modified

在这里插入图片描述
第二次请求:request头带上第一次请求返回的Last-ModifiedEtagStatus Code: 304 Not Modified

在这里插入图片描述
更改服务器资源图片,生成新的EtagLast-Modified,再次请求:Status Code: 200 OK

在这里插入图片描述

Happy Ending

写了一天终于完成,如果你觉得看了对你有帮助,那就给个鼓励吧!

源码地址:web-cache

参考文章:
实践这一次,彻底搞懂浏览器缓存机制
深入理解浏览器的缓存机制

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值