浏览器缓存是如何提升网站访问速度的
提升速度,降低负载
浏览器访问一个页面时,会请求加载HTML、CSS和JS等静态资源,并把这些内容渲染到屏幕上。
对浏览器来说,如果页面没有更新,每次都去请求服务器是没有必要的。所以,把下载的资源缓存起来,下次访问时直接读取本地数据,可以大大提高页面访问速度。
对于服务器来说,每个请求到达之后都会进行url解析,读取文件和返回数据等一系列操作,这都会有CPU和内存开销。因此,通过缓存减少不必要的请求,可以降低服务器的负载。
综上所述,为了提高网站的访问速度,降低服务器的负载,就有了浏览器缓存。
那么,浏览器缓存是怎么实现的呢?
过期时间
服务器在返回资源时指定过期时间,浏览器收到响应后把数据存起来。下一次请求时如果资源未过期,则返回本地缓存数据。
这是HTTP1.0的缓存方案,即通过Expires头字段指定过期时间。
Expires: Thu, 05 May 2022 08:13:07 GMT
由于Expires是一个绝对时间,所以要求浏览器和服务器的系统时间必需保持同步。否则,将会导致浏览器无法准确地判断过期时间。
为了解决这个问题,HTTP1.1使用的是相对时间,即max-age头字段。
cache-control: max-age=60
max-age=60表示资源有效时间为60s,由浏览器自己计算过期时间,自然也就不存在系统时间同步问题了。
当expires和max-age同时存在时,max-age优先级更高。
协商缓存
当缓存数据过期了,服务器资源未更新时,浏览器是没有必要请求新资源的。所以,为了进一步提升缓存效果,HTTP1.1设计了协商缓存:当缓存数据过期了,浏览器要跟服务器验证资源是否已更新,如果资源更新了再去请求新的数据。
那么,服务器如何验证资源是否已更新呢?
HTTP1.1提供了两种方案:
- 文件内容的hash值:对应头字段etag/ If-None-Match。
- 文件最后更新时间:对应头字段last-modified/ If-Modified-Since。
服务器返回资源时带上etag或last-modified。当浏览器缓存过期了,带上If-None-Match或If-Modified-Since请求服务器验证资源是否更新。服务器判断资源有更新,就返回200和新资源;否则返回304。
当etag和last-modified同时存在时,etag优先级更高。相对而言,etag精度更高:etag只在文件内容变化时更新,而last-modified更新时不一定代表文件内容有更新。
过期时间和协商缓存是浏览器缓存的核心功能。除此之外,cache-control还提供了其它指令,可以满足多种应用场景。
静态资源缓存优化
Cache-Control:max-age=31536000
对js/css/img等更新频率低的资源,可以设置一个过期时间(通常为一年)。 如果资源需要紧急更新,只需要更新html中引用的文件名。(所以html一般需要保持较高的新鲜度)
示例:
第一次请求:返回200,max-age=31536000 。
# request
GET /script.js HTTP/1.1# response
HTTP/1.1 200 OK
Content-Type: application/javascript
Cache-Control: max-age=31536000
第二次请求:返回200,显示数据来自本地缓存。

PS:当我们刷新页面或第二次在地址栏按回车键,都会直接请求服务器。为了验证本地缓存未过期的情况,需要打开新的tab访问页面。
HTML协商缓存优化
# 方法一
Cache-Control: no-cache
# 方法二
Cache-Control: max-age=0, must-revalidate
承接上文,HTML作为Web应用的主要载体,要求实时更新。
如果html没有及时更新,将会导致页面引用的js/css等无法更新。另外,如果涉及接口变更,前后端必须同步更新的情况,访问旧的html将会导致接口报错。
示例:
第一次请求:返回200,no-cache和Last-Modified/ETag。
# request
GET /index.html HTTP/1.1# response
HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Fri, 03 Jun 2022 07:32:28 GMT
ETag: "6299b90c-14f"
Cache-Control: no-cache
第二次请求:请求带上If-None-Match/If-Modified-Since,服务器验证资源未更新,返回304。
# request
GET /index.html HTTP/1.1
If-None-Match: "6299b90c-14f"
If-Modified-Since: Fri, 03 Jun 2022 07:32:28 GMT# response
HTTP/1.1 304 Not Modified
Last-Modified: Fri, 03 Jun 2022 07:32:28 GMT
ETag: "6299b90c-14f"
Cache-Control: no-cache
敏感数据禁止缓存
Cache-Control: no-store
禁止浏览器缓存资源(响应)和不使用缓存(请求)。适用于包含敏感信息等不希望缓存的场景。
示例:
第一次请求:返回200和no-store。
# request
GET /index.html HTTP/1.1# response
HTTP/1.1 200 OK
Content-Type: text/html
Cache-Control: no-store
第二次请求:请求服务器,返回200和新资源。
代理服务器缓存控制
Cache-Control:public,max-age=600,s-maxage=60
http缓存除了存在浏览器(private),还可以存在代理服务器(public)。例如常见的CDN,即降低了网络延迟,还能降低服务器的负载。
对于安全性要求高的资源,建议禁用公共缓存。因为数据一旦被代理服务器缓存下来,就多了一份被攻击的风险。
各大网站缓存方案
B站
- html:no-cache
- JS文件:max-age=31536000(1年),文件命名带版本号或指纹信息,方便及时更新。
- CSS文件:max-age=31536000,文件命名带版本号或指纹信息,方便及时更新。
- 图片:max-age=31536000,文件命名带版本号或指纹信息,方便及时更新。
- XHR请求: no-cache
微信
- html:public, max-age=500
- JS文件:max-age=31536000(1年),文件命名带版本号或指纹信息,方便及时更新。
- CSS文件:max-age=31536000,文件命名带版本号或指纹信息,方便及时更新。
- 图片:max-age=31536000,文件命名带版本号或指纹信息,方便及时更新。
- XHR请求:no-cache,must-revalidate
淘宝
- html:默认
- js文件:max-age=2592000(一个月),s-maxage=86400;文件命名带版本号或指纹信息,方便及时更新。
- CSS文件:max-age=2592000,s-maxage=3600;文件命名带版本号或指纹信息,方便及时更新。
- 图片:max-age=15552000;文件命名带版本号或指纹信息,方便及时更新。
新浪
- html: max-age=60
- js文件:max-age=31536000;max-age=14400;max-age=3600
- CSS文件:public, max-age=14400
- 图片:max-age=31536000(一年)
常见配置方案
- HTML缓存
通过 meta标签 的http-equiv和content来设置报文头:Cache-Control和Expires。
<meta http-equiv="Expires" content="Mon, 20 Jul 2013 23:00:00 GMT" />
<meta http-equiv="Cache-Control" content="max-age=7200" />
用meta标签的http-equiv属性来设置强缓存。用法简单,不需要服务器支持。适合更新频率低的页面。
- nginx缓存
当nginx作为静态资源服务器时,通过配置http头保证浏览器缓存行为一致。
# html使用协商缓存
location ~.*.html$
{add_header Cache-Control no-cache;# 作用跟Cache-Control no-cache一致;兼容HTTP/1.0add_header Pragma no-cache;
}# 对于更新频率低的,缓存有效时间可设置长一点。
location ~.*.(js|css|png|jpg)$
{expires 365d;
}
- webpack文件名hash
entry:{main: path.join(__dirname,'./main.js'),vendor: ['react', 'antd']
},
output:{path:path.join(__dirname,'./dist'),publicPath: '/dist/',filname: 'bundle.[contenthash].js'
}
通过webpack打包,自动给文件名加上hash值。其中,contenthash表示hash值由文件内容计算得到,内容不同产生的contenthash值也不一样。
总结
为了提高网站的访问速度,降低服务器的负载,就有了浏览器缓存。
浏览器缓存的核心是过期时间和协商缓存:服务器在返回资源时指定过期时间,浏览器收到响应后把数据存起来。下一次请求时如果资源未过期,则返回本地缓存数据;当缓存数据过期了,浏览器要跟服务器验证资源是否已更新,如果资源更新了再去请求新的数据,否则返回304。
浏览器缓存有很多的实际应用场景,例如:静态资源缓存优化、HTML协商缓存优化、敏感数据禁止缓存、代理服务器缓存控制。最后介绍了常见的配置方案,包括HTML、nginx和webpack等。
参考资料
MDN
HTTP 的缓存为什么这么设计?
HTTP缓存协议实战
前端缓存最佳实践
HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!
相关文章:
浏览器缓存是如何提升网站访问速度的
提升速度,降低负载 浏览器访问一个页面时,会请求加载HTML、CSS和JS等静态资源,并把这些内容渲染到屏幕上。 对浏览器来说,如果页面没有更新,每次都去请求服务器是没有必要的。所以,把下载的资源缓存起来&…...
Linux中几个在终端中有趣的命令
uhh…最近我不知道该更新些什么,所以就更新Linux几个很有趣的命令 文章目录前言1.命令:sl安装 sl输出2. 命令:telnet命令:fortune安装fortune4.命令:rev(反转)安装rev5. 命令:factor…...
快来来试试SpringBoot3 中的新玩意~
你还在用OpenFeign嘛?快来试试 SpringBoot3 中的这个新玩意!声明式HTTP调用 1、由来 Spring Boot3 去年底就已经正式发布,我也尝了一把鲜,最近有空会和小伙伴们慢慢聊聊 Spring Boot3 都给我们带来了哪些新东西。 今天我们就先…...
【寻人启事】达坦科技持续招人ing
❤️一起来探索前沿科技,做有意思的事情~ 我们是谁 达坦科技(DatenLord)专注于打造新一代开源跨云存储平台。通过软硬件深度融合的方式打通云云壁垒,实现无限制跨云存储、跨云联通,建立海量异地、异构…...
【C/C++基础练习题】简单函数练习题
🍉内容专栏:【C/C要打好基础啊】 🍉本文内容:简单函数使用练习题(复习之前写过的实验报告) 🍉本文作者:Melon西西 🍉发布时间 :2023.2.11 目录 1.给定某个年…...
【代码随想录训练营】【Day11】第五章|栈与队列|20. 有效的括号|1047. 删除字符串中的所有相邻重复项|150. 逆波兰表达式求值
20. 有效的括号 题目详细:LeetCode.20 由题可知,有效字符串需满足: 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括号。 那么,我们可以利用栈后进先出的特点&#x…...
基于云原生分布式存储ceph实现k8s数据持久化
文章目录1、初始化集群1.1 集群机器配置1.2 配置主机名1.3 配置hosts文件1.4、配置互信1.5、关闭防火墙1.6、关闭selinux1.7、配置Ceph安装源1.8、配置时间同步1.9、安装基础软件包2、安装ceph集群2.1 安装ceph-deploy2.2 创建monitor节点2.3 安装ceph-monitor2.4 部署osd服务2…...
SpringMVC获取请求参数
SpringMVC获取请求参数 通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的报文对象。 RequestMapping("/testServletAPI") // request表示当前请求 public String testServletAPI(H…...
详解浏览器从输入URL到页面展示的过程
用户发出 URL 请求到页面开始解析的这个过程,就叫做导航。 1. 用户输入 当用户在地址栏中输入一个查询关键字时,地址栏会判断输入的关键字是搜索内容,还是请求的 URL。 当用户输入关键字并键入回车之后,这意味着当前页面即将要…...
【吉先生的Java全栈之路】
吉士先生Java全栈学习路线🧡第一阶段Java基础: 在第一阶段:我们要认真听讲,因为基础很重要!基础很重要!基础很重要!!! 重要的事情说三遍。在这里我们先学JavaSE路线;学完之后我们要去学第一个可视化组件编程《GUI》;然后写个《贪吃蛇》游戏耍…...
第二章 Opencv图像处理基本操作
目录1.读取图像1-1.imread()方法2.显示图像2-1.imshow()方法2-2.waitKey()方法2-3.destroyAllWindows()方法2-4.小总结3.保存图像3-1.imwrite()方法4.查看图像属性4-1.常见的三个图像属性1.读取图像 要对一幅图像进行处理,第一件事就是要读取这幅图像。 1-1.imread(…...
字节一面:在浏览器地址栏输入一个 URL 后回车,背后发生了什么?
近段时间,有小伙伴面试字节,说遇到一个面试题: 在浏览器地址栏输入一个 URL 后回车,背后发生了什么? 这里尼恩给大家做一下系统化、体系化的梳理,使得大家可以充分展示一下大家雄厚的 “技术肌肉”…...
推荐3dMax三维设计十大插件
3dMax是一款功能非常强大的三维设计软件,但无论它的功能多么强大,也不可能包含所有三维方面的功能,这时候,第三方插件可以很好的弥补和增强3dMax的基本功能,下面就给大家介绍十款非常不错的3dMax插件。 森林包…...
Arduino IDE 2.0.6中 ESP32开发环境搭建笔记
Arduino IDE 2.0.6中 ESP32开发环境搭建 Arduino IDE2.0 已上线一段时间,以后ESP32的学习转至新的IDE中 ,需对开发环境进行。 Arduino IDE2.0与1.0有很大差异。原来环境搭建方法已完全不同。下文主要记录环…...
商品秒杀接口压测及优化
目录一、生成测试用户二、jmeter压测三、秒杀接口优化1、优化第一步:解决超卖2、优化第二步:Redis重复抢购3、优化第三步:Redis预减库存①商品初始化②预减库存一、生成测试用户 将UserUtils工具类导入到zmall-user模块中,运行生…...
NFC 项目前期准备工作
同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 了解项目信息,FAE联系方式,驱动源码等驱动合入内核配置DTS驱动设备节点验证Push nf…...
(C语言)数据的存储
问:1. 数据类型有哪五大类?2. 数据类型的作用是什么与什么?3. 整型又可以具体分为哪五个?为什么字符char也归属于整型?4. 浮点型又可以具体分为哪两类?5. 构造类型就是什么?具体分为哪四类&…...
C语言深度剖析之文件操作
💗 💗 博客:小怡同学 💗 💗 个人简介:编程小萌新 💗 💗 如果博客对大家有用的话,请点赞关注加关注 🌞 什么是文件 磁盘上的文件是文件。 但是在程序设计中,我们一般谈的文…...
RNN神经网络初探
目录1. 神经网络与未来智能2. 回顾数据维度和神经网络1. 神经网络与未来智能 2. 回顾数据维度和神经网络 循环神经网络,主要用来处理时序的数据,它对每个词的顺序是有要求的。 循环神经网络如何保存记忆功能? 当前样本只有 3 个特征&#x…...
【flinkx】【hdfs】【ing】Cannot obtain block length for LocatedBlock
一. 任务描述 使用flinkx去跑HDFS到HIVE的任务时,出现如下报错: CannotObtainBlockLengthException com.dtstack.flinkx.throwable.FlinkxRuntimeException: cant get file size from hdfs, file hdfs://xxx/.data/540240453caeb6fe4b3f118410a05315_2…...
云端AI模型基准测试:从参数迷信到效能优先的选型实战
1. 项目概述:一次颠覆认知的云端AI模型基准测试作为一名长期在本地部署AI智能体(我用的是OpenClaw)的实践者,模型选型一直是我工作流中的核心决策。过去几个月,我默认使用的都是阿里云出品的qwen3.5:397b-cloud。这个模…...
别再手动造数据了!用Python的imgaug库5分钟搞定深度学习图像增强(附关键点/边界框处理避坑指南)
深度学习图像增强实战:用imgaug打造高效数据流水线 在计算机视觉项目中,数据增强是提升模型泛化能力的关键步骤。传统手动处理方式不仅耗时耗力,还难以保证处理一致性。本文将深入探讨如何利用Python的imgaug库快速构建自动化图像增强流程&am…...
SpringBoot项目启动报错Could not resolve placeholder?别慌,这10种排查思路总有一种能帮你搞定
SpringBoot配置占位符解析失败的10种深度排查策略 当你正沉浸在SpringBoot项目的开发中,突然控制台抛出那行刺眼的红色错误——"Could not resolve placeholder xxx in value ${xxx}",这种场景对于Java开发者来说再熟悉不过。这个看似简单的报…...
Windows 10/11下MySQL 8.0.28安装失败?‘服务没有响应控制功能’报错保姆级修复指南
Windows平台MySQL安装报错终极解决方案:从"服务无响应"到完美运行 遇到MySQL安装过程中弹出"服务没有响应控制功能"的红色报错窗口时,很多开发者第一反应是重装系统或更换数据库——别急!这个看似复杂的错误其实90%以上源…...
WeChatMsg:如何用开源工具构建你的个人数字记忆库
WeChatMsg:如何用开源工具构建你的个人数字记忆库 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg…...
实测:2026 年国内直连 AI 一站式平台,聊天 / 绘画 / 论文 / 视频全搞定,不用翻墙不花冤枉钱
最近 AI 圈真的太卷了。ChatGPT 5.4、Gemini 3.1、Claude Code 轮番上新,多模态、长文本、代码 Auto Mode 一个比一个强。但普通用户想用明白,真的太折腾。先说说我踩过的三大坑,句句大实话网络糟心到崩溃官网打不开、地区不可用、加载转圈、…...
HoRain云--PHP日期格式化函数date()详解与最佳实践
🎬 HoRain 云小助手:个人主页 ⛺️生活的理想,就是为了理想的生活! ⛳️ 推荐 前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。 目录 ⛳️ 推荐 …...
【2026实测】论文AI率从81%降至个位数?8款降AIGC工具深度横测
内容ai率检测数值太高,不得不熬夜改了一遍又一遍,润色到想吐,结果检测报告上数字还是不尽人意,截止日期越逼越近,真的是没办法了。 我花了整整三天,把2026全网热门的几十款降AI工具通通测了个遍࿰…...
从怀疑到信服:VR如何从娱乐玩具进化为现实增强工具
1. 从怀疑到信服:一个技术怀疑论者的VR认知重塑之旅我不是那种会第一时间冲进苹果店排队买最新款手机的人,甚至可以说,我对新科技抱有一种近乎“卢德主义”的警惕。每当有新的技术浪潮涌来,我的第一反应不是兴奋,而是审…...
使用 llama.cpp + MTP 分支实现 1.5 倍 Token 输出加速实战指南
使用 llama.cpp MTP 分支实现 1.5 倍 Token 输出加速实战指南 摘要:本文详细介绍如何通过 llama.cpp 的 MTP(Multi-Token Prediction)PR 分支,配合 Qwen3.6-27B-MTP GGUF 量化模型,实现推理时每秒输出 token 数量翻倍…...
