不废话,代码实践带你掌握 强缓存、协商缓存!,2024年最新完美讲解内存缓存LruCache实现原理

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

  • static/css/index.css

.box {

width: 500px;

height: 300px;

background-image: url(‘…/image/guang.jpg’);

background-size: 100% 100%;

color: #000;

}

  • static/image/guang.jpg

e257eb48ee42edf2db0533763fec3c0b.png

  • index.js

const Koa = require(‘koa’)

const fs = require(‘fs’)

const path = require(‘path’)

const mimes = {

css: ‘text/css’,

less: ‘text/css’,

gif: ‘image/gif’,

html: ‘text/html’,

ico: ‘image/x-icon’,

jpeg: ‘image/jpeg’,

jpg: ‘image/jpeg’,

js: ‘text/javascript’,

json: ‘application/json’,

pdf: ‘application/pdf’,

png: ‘image/png’,

svg: ‘image/svg+xml’,

swf: ‘application/x-shockwave-flash’,

tiff: ‘image/tiff’,

txt: ‘text/plain’,

wav: ‘audio/x-wav’,

wma: ‘audio/x-ms-wma’,

wmv: ‘video/x-ms-wmv’,

xml: ‘text/xml’,

}

// 获取文件的类型

function parseMime(url) {

// path.extname获取路径中文件的后缀名

let extName = path.extname(url)

extName = extName ? extName.slice(1) : ‘unknown’

return mimes[extName]

}

// 将文件转成传输所需格式

const parseStatic = (dir) => {

return new Promise((resolve) => {

resolve(fs.readFileSync(dir), ‘binary’)

})

}

const app = new Koa()

app.use(async (ctx) => {

const url = ctx.request.url

if (url === ‘/’) {

// 访问根路径返回index.html

ctx.set(‘Content-Type’, ‘text/html’)

ctx.body = await parseStatic(‘./index.html’)

} else {

const filePath = path.resolve(__dirname, .${url})

// 设置类型

ctx.set(‘Content-Type’, parseMime(url))

// 设置传输

ctx.body = await parseStatic(filePath)

}

})

app.listen(9898, () => {

console.log(‘start at port 9898’)

})

启动页面

现在你可以在终端中输入nodemon index,看到下方的显示,则代表成功启动了服务

32f68807b66eb793ae3536d004b702d6.png

此时你可以在浏览器链接里输入http://localhost:9898/,打开看到如下页面,则代表页面访问成功!!!

966e81c21c9cc44f2c02871ea42d29e6.png

HTTP缓存种类


HTTP缓存常见的有两类:

  • 强缓存:可以由这两个字段其中一个决定

  • expires

  • cache-control(优先级更高)

  • 协商缓存:可以由这两对字段中的一对决定

  • Last-Modified,If-Modified-Since

  • Etag,If-None-Match(优先级更高)

强缓存


接下来我们就开始讲强缓存

expires

我们只需设置响应头里expires的时间为当前时间 + 30s就行了

app.use(async (ctx) => {

const url = ctx.request.url

if (url === ‘/’) {

// 访问根路径返回index.html

ctx.set(‘Content-Type’, ‘text/html’)

ctx.body = await parseStatic(‘./index.html’)

} else {

const filePath = path.resolve(__dirname, .${url})

// 设置类型

ctx.set(‘Content-Type’, parseMime(url))

// 设置 Expires 响应头

const time = new Date(Date.now() + 30000).toUTCString()

ctx.set(‘Expires’, time)

// 设置传输

ctx.body = await parseStatic(filePath)

}

})

然后我们在前端页面刷新,我们可以看到请求的资源的响应头里多了一个expires的字段

85b96c3a396c6eff76a96d2419899ad4.png

并且,在30s内,我们刷新之后,看到请求都是走memory,这意味着,通过expires设置强缓存的时效是30s,这30s之内,资源都会走本地缓存,而不会重新请求

a38294c98d78258f3776280dbab9ec8a.png

注意点:有时候你Nodejs代码更新了时效时间,但是发现前端页面还是在走上一次代码的时效,这个时候,你可以把这个Disabled cache打钩,然后刷新一下,再取消打钩

5011983132f60f969d14689bdf25091f.png

cache-control

其实cache-controlexpires效果差不多,只不过这两个字段设置的值不一样而已,前者设置的是秒数,后者设置的是毫秒数

app.use(async (ctx) => {

const url = ctx.request.url

if (url === ‘/’) {

// 访问根路径返回index.html

ctx.set(‘Content-Type’, ‘text/html’)

ctx.body = await parseStatic(‘./index.html’)

} else {

const filePath = path.resolve(__dirname, .${url})

// 设置类型

ctx.set(‘Content-Type’, parseMime(url))

// 设置 Cache-Control 响应头

ctx.set(‘Cache-Control’, ‘max-age=30’)

// 设置传输

ctx.body = await parseStatic(filePath)

}

})

前端页面响应头多了cache-control这个字段,且30s内都走本地缓存,不会去请求服务端

1c1bb2939c388dbdfdecd444a5949a3d.png

协商缓存


强缓存不同的是,强缓存是在时效时间内,不走服务端,只走本地缓存;而协商缓存是要走服务端的,如果请求某个资源,去请求服务端时,发现命中缓存则返回304,否则则返回所请求的资源,那怎么才算命中缓存呢?接下来讲讲

Last-Modified,If-Modified-Since

简单来说就是:

  • 第一次请求资源时,服务端会把所请求的资源的最后一次修改时间当成响应头中Last-Modified的值发到浏览器并在浏览器存起来

  • 第二次请求资源时,浏览器会把刚刚存储的时间当成请求头中If-Modified-Since的值,传到服务端,服务端拿到这个时间跟所请求的资源的最后修改时间进行比对

  • 比对结果如果两个时间相同,则说明此资源没修改过,那就是命中缓存,那就返回304,如果不相同,则说明此资源修改过了,则没命中缓存,则返回修改过后的新资源

// 获取文件信息

const getFileStat = (path) => {

return new Promise((resolve) => {

fs.stat(path, (_, stat) => {

resolve(stat)

})

})

}

app.use(async (ctx) => {

const url = ctx.request.url

if (url === ‘/’) {

// 访问根路径返回index.html

ctx.set(‘Content-Type’, ‘text/html’)

ctx.body = await parseStatic(‘./index.html’)

} else {

const filePath = path.resolve(__dirname, .${url})

const ifModifiedSince = ctx.request.header[‘if-modified-since’]

const fileStat = await getFileStat(filePath)

console.log(new Date(fileStat.mtime).getTime())

ctx.set(‘Cache-Control’, ‘no-cache’)

ctx.set(‘Content-Type’, parseMime(url))

// 比对时间,mtime为文件最后修改时间

if (ifModifiedSince === fileStat.mtime.toGMTString()) {

ctx.status = 304

} else {

ctx.set(‘Last-Modified’, fileStat.mtime.toGMTString())

ctx.body = await parseStatic(filePath)

}

}

})

打开全栈工匠技能包-1小时轻松掌握SSR

两小时精通jq+bs插件开发

生产环境下如歌部署Node.js

网易内部VUE自定义插件库NPM集成

谁说前端不用懂安全,XSS跨站脚本的危害

webpack的loader到底是什么样的?两小时带你写一个自己loader

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
FlNzQwNmUzMWI4NjM0NTk3ZTFjOWQwN19oZC5qcGc?x-oss-process=image/format,png)

webpack的loader到底是什么样的?两小时带你写一个自己loader

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-iPyoRZ1D-1713445536642)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值