架构高性能网站秘笈(三)——浏览器缓存

什么是浏览器缓存?

《架构高性能网站秘笈(二)——动态内容缓存》中我们知道,当不同用户请求相同数据时,动态内容缓存能够避免服务器的重复计算,从而降低用户的等待时间。但如果是同一个用户请求相同的数据,即使服务器能避免重复计算,但仍需将重复的数据传递给浏览器。若使用浏览器缓存,则同一个用户请求相同的数据时,浏览器只需从自己本地读取,无需从服务器上获取。从而大大降低用户的等待时间,减少了服务器的压力,可谓一箭双雕!

浏览器是如何处理缓存的?

是否启用浏览器缓存是通过HTTP协议控制的。 浏览器在接收服务器传来的页面后,会将页面存入本地缓存。如果响应头中包含了页面的过期时间,那么当用户请求相同的页面时,浏览器会询问服务器是否可以使用缓存页面,若服务器同意使用缓存,则返回304状态码;若服务器不同意,则将新的页面返回给浏览器,并携带200状态码。

此外,如果响应头中未包含启用浏览器缓存属性的话,浏览器仍然会缓存当前页,但下次请求相同页面时浏览器会直接向服务器请求新的页面,而不会询问是否使用缓存页面。

如何实现浏览器缓存?

1. last-modified

如果服务器向浏览器返回的响应头中包含last-modified属性,那么浏览器会将该属性与页面一起存入本地缓存。 当用户请求相同的页面时,浏览器发送的请求头中会携带属性:

If-Modified-Since:XXXXX

服务器会根据该值判断是否可以使用缓存页面,若可以使用缓存,则返回304状态码,若不可以使用缓存,则返回最新的页面,并携带200状态码。

注意:如果服务器的响应头中未包含last-modified属性,那么用户在请求相同页面时,浏览器中也不会包含If-Modified-Since:XXXXX属性,从而服务器也不会判断是否使用浏览器缓存,而是直接返回页面。

2. 采用ETag属性

ETag属性和Last-Modified属性类似。ETag属性值是一串字符串。 若服务器的响应头中包含了ETag属性,那么浏览器会将页面和ETage属性值一起缓存;当用户请求相同的页面时,浏览器会读区缓存的ETag值,并作为请求头的If-None-Match:”xxxxx”属性发送给服务器;服务器收到该属性后,判断是否允许浏览器使用缓存页面,若允许则返回304状态码,若不允许直接返回新的页面,并携带200状态码。

如何彻底实现浏览器缓存?

刚才的浏览器缓存还会涉及到浏览器与服务器的通信,因为浏览器需要向服务器询问是否使用本地缓存,而这些通信仍然需要消耗较多的用户等待时间。能否避免浏览器的这种询问呢?

1.采用Expires属性

Expires属性表示过期时间。 服务器只需在响应头中添加Expires属性,浏览器会将该属性与页面一起缓存。当用户再次请求相同的页面时,浏览器会将该页面的Expires与当前系统时间进行比较,判断是否过期;若尚未过期,则直接使用本地页面。

但是,如果用户的本地时间是错误的,那么Expires属性无法发挥它的作用,此时需要使用Cache-Control属性。

2.采用Cache-Control属性

Cache-Control:max-age=3600表示页面从当前时间开始3600秒后过期。从而能解决用户本地时间错误的问题。

浏览器缓存的优点

  1. 浏览器缓存能够大大降低(甚至消除)服务器的网络IO,从而服务器能够租用更廉价的带宽。
  2. 浏览器缓存能减少(甚至消除)服务器查询缓存的操作、数据库操作,从而减小服务器压力,提高并发数。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏抠抠空间

Flask之session相关

除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥...

482
来自专栏Java架构沉思录

详解HTTP缓存

HTTP缓存是一项重要且常见的web性能优化手段。当通过浏览器发送HTTP请求时,如果浏览器本地有所要请求的文档副本,那么浏览器可以直接从本地存储中读取该文档,...

3265
来自专栏Golang语言社区

selec/poll中的读写事件和epoll中的读写事件

在Linux网络编程中,常常使用select和poll来做事件触发,监听socket的读写状态,然后进行读写操作。现在新的linux内核中,增加了epoll事件...

3124
来自专栏Jerry的SAP技术分享

如何使用jMeter发送两个逻辑上相关的HTTP请求

在前一篇文章使用jMeter构造大量并发的随机HTTP请求里我通过jMeter构造了大量的HTTP GET并发请求,对服务器产生了大量读操作。

3576
来自专栏Java编程技术

异步打印日志的一点事

最近刚刚结束转岗以来的第一次双11压测,收获颇多,难言言表, 本文就先谈谈异步日志吧,在高并发高流量响应延迟要求比较小的系统中同步打日志已经满足不了需求了,同步...

491
来自专栏小特工作室

基于Ado.Net的日志组件

软件开发,离不开对日志的操作,它可以帮助我们查找和检测问题。好的日志组件可以对于整个系统来说,至关重要 在NaviSoft产品中,日志组件也占有非常重要的份量。...

1989
来自专栏Danny的专栏

【事务隔离级别】——三步了解数据库的事务隔离级别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

803
来自专栏Java编程技术

何为脏读、不可重复读、幻读

事务的隔离性是指多个事务并发执行的时候相互之间不受到彼此的干扰的特性,隔离性是事务ACID特性中的I,根据隔离程度从低到高分为Read Uncommitted(...

1243
来自专栏编程

Python接口自动化-3-POST请求

POST请求 HTTP协议规定post提交的数据必须放在消息主体中,但是协议并没有规定必须使用什么编码方式。服务端通过是根据请求头中的Content-Type字...

2508
来自专栏淡定的博客

axios

772

扫码关注云+社区