当前位置: 首页 > news >正文

浏览器缓存是如何提升网站访问速度的

提升速度,降低负载

浏览器访问一个页面时,会请求加载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,显示数据来自本地缓存。

image.png

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 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

相关文章:

浏览器缓存是如何提升网站访问速度的

提升速度&#xff0c;降低负载 浏览器访问一个页面时&#xff0c;会请求加载HTML、CSS和JS等静态资源&#xff0c;并把这些内容渲染到屏幕上。 对浏览器来说&#xff0c;如果页面没有更新&#xff0c;每次都去请求服务器是没有必要的。所以&#xff0c;把下载的资源缓存起来&…...

Linux中几个在终端中有趣的命令

uhh…最近我不知道该更新些什么&#xff0c;所以就更新Linux几个很有趣的命令 文章目录前言1.命令&#xff1a;sl安装 sl输出2. 命令&#xff1a;telnet命令&#xff1a;fortune安装fortune4.命令&#xff1a;rev&#xff08;反转&#xff09;安装rev5. 命令&#xff1a;factor…...

快来来试试SpringBoot3 中的新玩意~

你还在用OpenFeign嘛&#xff1f;快来试试 SpringBoot3 中的这个新玩意&#xff01;声明式HTTP调用 1、由来 Spring Boot3 去年底就已经正式发布&#xff0c;我也尝了一把鲜&#xff0c;最近有空会和小伙伴们慢慢聊聊 Spring Boot3 都给我们带来了哪些新东西。 今天我们就先…...

【寻人启事】达坦科技持续招人ing

​​​​​​​ ❤️一起来探索前沿科技&#xff0c;做有意思的事情~ 我们是谁 达坦科技&#xff08;DatenLord&#xff09;专注于打造新一代开源跨云存储平台。通过软硬件深度融合的方式打通云云壁垒&#xff0c;实现无限制跨云存储、跨云联通&#xff0c;建立海量异地、异构…...

【C/C++基础练习题】简单函数练习题

&#x1f349;内容专栏&#xff1a;【C/C要打好基础啊】 &#x1f349;本文内容&#xff1a;简单函数使用练习题&#xff08;复习之前写过的实验报告&#xff09; &#x1f349;本文作者&#xff1a;Melon西西 &#x1f349;发布时间 &#xff1a;2023.2.11 目录 1.给定某个年…...

【代码随想录训练营】【Day11】第五章|栈与队列|20. 有效的括号|1047. 删除字符串中的所有相邻重复项|150. 逆波兰表达式求值

20. 有效的括号 题目详细&#xff1a;LeetCode.20 由题可知&#xff0c;有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括号。 那么&#xff0c;我们可以利用栈后进先出的特点&#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作为控制器方法的形参&#xff0c;此时HttpServletRequest类型的参数表示封装了当前请求的报文对象。 RequestMapping("/testServletAPI") // request表示当前请求 public String testServletAPI(H…...

详解浏览器从输入URL到页面展示的过程

用户发出 URL 请求到页面开始解析的这个过程&#xff0c;就叫做导航。 1. 用户输入 当用户在地址栏中输入一个查询关键字时&#xff0c;地址栏会判断输入的关键字是搜索内容&#xff0c;还是请求的 URL。 当用户输入关键字并键入回车之后&#xff0c;这意味着当前页面即将要…...

【吉先生的Java全栈之路】

吉士先生Java全栈学习路线&#x1f9e1;第一阶段Java基础: 在第一阶段:我们要认真听讲,因为基础很重要!基础很重要!基础很重要!!! 重要的事情说三遍。在这里我们先学JavaSE路线&#xff1b;学完之后我们要去学第一个可视化组件编程《GUI》&#xff1b;然后写个《贪吃蛇》游戏耍…...

第二章 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.读取图像 要对一幅图像进行处理&#xff0c;第一件事就是要读取这幅图像。 1-1.imread(…...

字节一面:在浏览器地址栏输入一个 URL 后回车,背后发生了什么?

近段时间&#xff0c;有小伙伴面试字节&#xff0c;说遇到一个面试题&#xff1a; 在浏览器地址栏输入一个 URL 后回车&#xff0c;背后发生了什么&#xff1f; 这里尼恩给大家做一下系统化、体系化的梳理&#xff0c;使得大家可以充分展示一下大家雄厚的 “技术肌肉”&#xf…...

推荐3dMax三维设计十大插件

3dMax是一款功能非常强大的三维设计软件&#xff0c;但无论它的功能多么强大&#xff0c;也不可能包含所有三维方面的功能&#xff0c;这时候&#xff0c;第三方插件可以很好的弥补和增强3dMax的基本功能&#xff0c;下面就给大家介绍十款非常不错的3dMax插件。 森林包&#xf…...

Arduino IDE 2.0.6中 ESP32开发环境搭建笔记

Arduino IDE 2.0.6中 ESP32开发环境搭建 Arduino IDE2.0 已上线一段时间&#xff0c;以后ESP32的学习转至新的IDE中 &#xff0c;需对开发环境进行。 Arduino IDE&#xff12;.&#xff10;与&#xff11;.&#xff10;有很大差异。原来环境搭建方法已完全不同。下文主要记录环…...

商品秒杀接口压测及优化

目录一、生成测试用户二、jmeter压测三、秒杀接口优化1、优化第一步&#xff1a;解决超卖2、优化第二步&#xff1a;Redis重复抢购3、优化第三步&#xff1a;Redis预减库存①商品初始化②预减库存一、生成测试用户 将UserUtils工具类导入到zmall-user模块中&#xff0c;运行生…...

NFC 项目前期准备工作

同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 了解项目信息,FAE联系方式,驱动源码等驱动合入内核配置DTS驱动设备节点验证Push nf…...

(C语言)数据的存储

问&#xff1a;1. 数据类型有哪五大类&#xff1f;2. 数据类型的作用是什么与什么&#xff1f;3. 整型又可以具体分为哪五个&#xff1f;为什么字符char也归属于整型&#xff1f;4. 浮点型又可以具体分为哪两类&#xff1f;5. 构造类型就是什么&#xff1f;具体分为哪四类&…...

C语言深度剖析之文件操作

&#x1f497; &#x1f497; 博客:小怡同学 &#x1f497; &#x1f497; 个人简介:编程小萌新 &#x1f497; &#x1f497; 如果博客对大家有用的话&#xff0c;请点赞关注加关注 &#x1f31e; 什么是文件 磁盘上的文件是文件。 但是在程序设计中&#xff0c;我们一般谈的文…...

RNN神经网络初探

目录1. 神经网络与未来智能2. 回顾数据维度和神经网络1. 神经网络与未来智能 2. 回顾数据维度和神经网络 循环神经网络&#xff0c;主要用来处理时序的数据&#xff0c;它对每个词的顺序是有要求的。 循环神经网络如何保存记忆功能&#xff1f; 当前样本只有 3 个特征&#x…...

【flinkx】【hdfs】【ing】Cannot obtain block length for LocatedBlock

一. 任务描述 使用flinkx去跑HDFS到HIVE的任务时&#xff0c;出现如下报错&#xff1a; CannotObtainBlockLengthException com.dtstack.flinkx.throwable.FlinkxRuntimeException: cant get file size from hdfs, file hdfs://xxx/.data/540240453caeb6fe4b3f118410a05315_2…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...

Mysql故障排插与环境优化

前置知识点 最上层是一些客户端和连接服务&#xff0c;包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念&#xff0c;为通过安全认证接入的客户端提供线程。同样在该层上可…...