前言
在前端开发中,网站性能是非常重要的一点,一个优秀的缓存策略能够减少带宽,降低网络负荷,减少延迟。本文简单聊一下浏览器缓存。
缓存分类
Web缓存分为多种, 如数据库缓存、DNS缓存、CDN缓存,以及浏览器缓存等。
浏览器缓存
一、什么是浏览器缓存?
简单一点说,浏览器缓存就是将通过HTTP请求获取的资源保存在本地的一种行为。
二、缓存位置
- memory cache
- disk cache
三、三级缓存原理 (访问缓存优先级)
- 先在内存中查找,如果有,直接加载。
- 如果内存中不存在,则在硬盘中查找,如果有直接加载。
- 如果硬盘中也没有,那么就进行网络请求。
- 请求获取的资源缓存到硬盘和内存。
四、浏览器缓存的分类
- 强缓存 浏览器在加载资源时,会先根据本地缓存资源的 header 中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求。在chrome控制台的Network选项中可以看到该请求返回200的状态码,并且Size显示from disk cache或from memory cache。强缓存可以通过设置两种 HTTP Header 实现:Expires 和 Cache-Control。
- 协商缓存 当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据 header 中的部分信息来判断是否命中缓存。如果命中,则返回 304 ,告诉浏览器资源未更新,可使用本地的缓存。这里的 header 中的信息指的是 Last-Modify/If-Modify-Since 和 ETag/If-None-Match。
缓存机制
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回304,继续使用缓存。具体流程如下。
实践
一、搭建服务
这里用Egg.js 框架起一个WEB服务器(是阿里开源的基于Koa2的企业级 Node.js 框架)。 对强缓存的Cache-Control和协商缓存的Etag 进行测试。
1.项目初始化
2.编写 Controller
3.配置路由映射
4.静态资源
Egg 内置了 static 插件,线上环境建议部署到 CDN,无需该插件。static 插件默认映射 /public/* -> app/public/*
目录 此处,我们把静态资源都放到 app/public
目录即可:
5.模板渲染
6.启动服务
二、强缓存和协商缓存实践。
主要演示下cacheControl与ETag设置的效果
此时,浏览器把ppd.png图片缓存到了磁盘和内存中,刷新页面后会先在内存中找到资源,如下图所示:
关闭Tab页面,由于内存是存在进程中的,关闭页面,内存中的资源被释放掉,磁盘中的资源是永久性的,所以还存在。根据三级缓存原理,重新打开页面,便会在磁盘中找到资源。
刚刚对资源的有效期设置的是600秒,600秒后重新刷新页面,可以清楚的看到,强缓存失效了,并命中了协商缓存。如下图所示。
egg-static静态服插件,基础与koa的静态插件 koa-static-cache.Uses MD5 hash sum as an ETag.
验证服务器端资源变化时,协商缓存是否失效,修改ppd.png,刷新页面,此时,消息头结果如下:
可以看出, If-None-Match !== ETag,协商缓存失效,浏览器重新向服务器发起请求。
结语
本文简单介绍了下浏览器的缓存,希望对大家有点小的帮助,限于篇幅,每一部分的描述都比较简略,仅起到抛砖引玉之用。如有错误,还望指出。