网络请求实战-缓存、缓存清理和HTTP缓存

本文介绍了缓存的基本概念,包括CPU和内存中的缓存作用,以及布隆过滤器。重点讲解了三种缓存清空策略:FIFO(先进先出)、LFU(最少使用频率)和LRU(最近最少使用),并提供了JavaScript实现示例。此外,还探讨了HTTP缓存的相关设置,如Cache-Control、强制缓存和协商缓存,以及在实际应用中的注意事项。
摘要由CSDN通过智能技术生成

目录

缓存介绍

清空策略(FIFO)

实战:fifo的memory函数

实战:LRU算法

HTTP缓存

Cache-Control

强制缓存

协商缓存

协商缓存-2(用的最多的)

小结


缓存介绍

早期cpu,内存设计上都有缓存

存储将被用到的数据,让数据访问更快

布隆过滤器(效率更高,牺牲缓存命中率)

  • 命中:在缓存中找到了请求的数据
  • 不命中/穿透:缓存中没有需要的数据
  • 命中率:命中次数/总次数
  • 缓存大小:缓存中一共可以存多少数据
  • 清空策略:如果缓存空间不够数据如何被替换

清空策略(FIFO)

1.先进先出

思考:如果是Javascript缓存,用Map还是Array(Map易读取,Array易清空)

2.LFU-Least Frequently used

优先清除命中次数少的,根据使用频率

内部实现用数组还是优先级队列?(量大的话用数组遍历效率低,可以考虑用优先级队列)

3.LRU-Least recently used

优先清除太久没有使用的,保留最近被使用的缓存,更新最近调用时间

思考:内部实现用数组还是优先级队列?

实战:fifo的memory函数

缓存成立的环境,会做哪些事情

通常是在浏览器上,在端上,整体缓存设置大小限制的

// 先进先出实现方法
function memory(f, maxSize = 10) {
  // [{hash, value}]
  const cache = []
  return (...args) => {
    const hash = args.join(',')
    const item = cache.find(x => x.hash === hash)// 循环遍历,找到x.hash === hash 的x   
    if(item) {
      return item.value
    }
    const result = f(...args)
    cache.push({
      hash,
      value: result
    })
    if(cache.length > maxSize) {
      cache.shift() // 移除第一个值
    }
    return result
  }
}
// 1 1 2 3 5 8 13
// 斐波那契数列(Fibonacci sequence),
// 又称黄金分割数列
function fib(n) {
  if(n === 1 || n === 2) {
    return 1
  }
  //  递归,前面2个数的和
  // 因为是递归函数所以,下面mfib用外面那个使用缓存的mfib
  return mfib(n-1) + mfib(n-2) 
}
const mfib = memory(fib, 10)
2^n // 2的n次方
console.log(fib(40))

实战:LRU算法

缓存越来越多的话,会采取的策略

更新最近调用时间

// 优先清除太久没有使用的,保留最近被使用的缓存,更新最近调用时间
function memory(f, maxSize = 10) {
  // [{hash, value}]
  let cache = [] // 重新附过值用let
  //let cache = {}
  return (...args) => {
    const hash = args.join(',')
    const item = cache.find(x => x.hash === hash)
    if(item) {
      item.time = new Date().getTime() // 更新调用时间戳
      return item.value
    }
    const result = f(...args)
    cache.push({
      hash,
      value: result,
      time: new Date().getTime() // 新增时间
    })
    if(cache.length > maxSize) {// 删掉时间戳最小的值
      let min = Infinity // 正无穷
      let minItem = null
      for(let item of cache) {
        if(item.time <min) { // 循环比对,把时间戳最小值赋值给min,minItem
          min = item.time
          minItem = item
        }
      }
      cache = cache.filter(x => x !== minItem) // 保留除了时间戳最小值的数据
    }
    return result
  }
}
// 1 1 2 3 5 8 13
function fib(n) {
  if(n === 1 || n === 2) {
    return 1
  }
  return mfib(n-1) + mfib(n-2)
}
const mfib = memory(fib, 10)
console.log(fib(40))

 建议用优先级队列,更新一下,上面方法里的on循环

HTTP缓存

Cache-Control

定义所有缓存都要遵守的行为

可缓存性

  • public:允许所有方缓存
  • private:只允许浏览器缓存
  • no-cache:每次必须先询问服务器资源是否已经更新
  • no-store:不使用缓存

缓存期限

  • max-age:秒(存储周期)
  • s-maxage:秒(共享缓存如代理等,存储周期)

强制缓存

强制使用缓存,不去服务器对比;(缓存生效不再发送请求)

Cache-Control: max-age=600(多用这个)

Expires:(用的少)

const express = require('express')
const app = express()
app.get('/x', (req, res) => {
    // max-age=0 === no-cache
  res.set("Cache-Control", 'max-age=600') // 强制缓存,一般用于一定时间内不会变的静态文件
  res.send("x6")
})
app.listen(3000)
// fetch("/x") // Code: 200 OK (from disk cache)

请求页面,请求接口会用304协商缓存no-cache

协商缓存

协商使用缓存,每次需要向服务器请求对比,缓存生效不传回body

返回: Last-Modified:

请求:If-Modified-Since:

const express = require('express')
const app = express()
app.set('etag', false)// etag也是一种协商缓存,关掉干扰因素
app.get('/x', (req, res) => {
  res.set("Last-Modified", 'Tue Sep 28 2021 23:41:43 GMT+0800') // 协商缓存,数据更新的最后时间,比较好用
  res.send("x6")
})
app.listen(3000)

协商缓存-2(用的最多的)

返回:E-Tag:1234567

请求:If-None-Match:1234567

小结

  • 发布新的静态资源的时候,如何更新缓存?

1.每次发布的静态资源文件名都不同(大厂最多策略)

  • HTTP缓存有大小限制吗?FIFO还是LRU

HTTP有大小限制,用端的时候要和端上的同学协商用多大的缓存,

浏览器有自己的限制;CDN也会有限制,只是通常触发不到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值