1.前言

  • 由来:默认环境中,当浏览器重复访问一个资源时,为节省资源与性能,浏览器将其缓存,后续的请求不再从服务器下载该资源,而是直接从本地缓存中读取,默认时没有强制缓存的
  • 副作用:当服务器资源更新时,浏览器无法得知,依旧加载的是旧资源
  • 缓存类型:强制缓存和协商缓存

2.强制缓存

  • 作用:告诉浏览器,强制缓存生效期间,再次拿当前资源不要发请求,直接读取磁盘
  • 通过 Expires 设定缓存的过期时间,这个时间是服务器设定的,但是如果客户端与服务端时间不同步,就会产生问题,所以不推荐使用,现在已被后面的 Cache-Control 替代
//强制缓存(设置过期时间)
var expires = new Date()
//1分钟过期
expires.setMinutes(expires.getMinutes() + 1)
res.setHeader('Expires', expires.toUTCString())

  • 通过 Cache-Control 设定缓存有效时长(秒),以客户端时间为准,往后计算缓存有效期
res.setHeader("Cache-Control","max-age=7200")

3.协商缓存

  • 说明:顾名思义,就是在使用本地缓存之前,向服务器发起GET请求,与之协商当前的缓存是否已经过期,如果已经过期,则下载最新的资源,如果没过期,则读取缓存
  • 原理:资源缓存时,附带一个标识(文件最终修改时间,或者文件内容hash),下次请求时然后拿这个标识与服务器的标识 做对比,如果不一致,则返回最新资源,如果一直,则返回返回状态码 304,让浏览器读本地缓存
  • 注意:需要设定 Cache-Control 为 no-cache (这里的no-cache含义并不是说不要缓存,而说的是协商缓存,只有设定为no-store才是禁用缓存,设置 max-age 也是可以启用缓存的,只不过此时强制换成优先级比协商缓存高)
  • last-modified:通过获取文件最终修改时间作为标识进行判断,下一次请求时,请求头会自动添加 "if-modified-since" 字段并带上之前返回的last-modified的值,服务器就可以知道当前资源的最终修改时间,以此来判断返回的内容。这种方式有2个弊端:第一,文件可能被动过,但是里面内容没变,可能只是重命名,第二,修改时间戳精确到秒,做不到毫秒级的识别判定
//获取文件
var data = fs.readFileSync('./www/index.js')
//获取文件时间
var {mtime} = fs.statSync('./www/index.js')
//设置最终修改时间
res.setHeader("last-modified", mtime.toUTCString())
//开启协商缓存
res.setHeader('Cache-Control','no-cache') //对比协商缓存的时间,来确定返回结果
var ifModifiedSince = req.headers["if-modified-since"]
if(ifModifiedSince == mtime.toUTCString()){
//告诉浏览器资源未发生变化,让他读缓存
res.statusCode = 304
res.end()
}else{
//返回图片
res.end(data)
}





  • Etag:通过文件内容进行hash运算生成字符串(hash运算使用的包名叫 etag),以此带代替last-modified,下一次请求时,请求头会自动添加 "If-None-Match" 字段并带上之前返回的Etag的值。缺点是hash运算计算开销大,影响性能
//获取文件
var data = fs.readFileSync('./www/index.js')
//hash运算生成字符串
var etagContent = etag(data)
//添加到响应头
res.setHeader('etag',etagContent)
//开启协商缓存
res.setHeader('Cache-Control','no-cache') //判断内容是否发生变化
var ifNoneMatch = req.headers["if-none-match"]
if(ifNoneMatch == etagContent){
//告诉浏览器资源未发生变化,让他读缓存
res.statusCode = 304
res.end()
}else{
//返回图片
res.end(data)
}



4.缓存策略

  • HTML文件:HTML文件包含了很多资源的引用,推荐使用协商缓存,当文件修改时才获取最新版本
  • 图片,字体文件等静态资源:这类资源要么不改,要么会整体替换掉,推荐使用强制缓存,但是要注意缓存的时间,缓存的东西太多客户端有压力
  • 固定URL的js,css文件:这类文件修改频繁,推荐使用协商缓存,当文件修改时才获取最新版本
  • 编译后的js,css文件:这里文件常见于脚手架项目,打包编译后文件名是随机变动的,和图片类似,推荐使用强制缓存

5.动态资源链接

  • 原理:当一个请求路径不变,但是携带的参数发生变化时,浏览器视为新请求,不读取缓存数据
//在资源链接后面添加版本号(v=100),修改通过这个版本号(v=101),强制客户端更新资源
<script src="./index.js?v=100"></script>
  • 全局控制:对资源链接的版本号进行动态拼接,只要修改系统版本号,所有资源强制升级

6.手动清除缓存

  • F12->网络->选中请求->清除缓存

  • 页面强制重载

7.meta标签中的Cache-Control

  • 语法
<meta http-equiv="Cache-Control" content="no-cache">
  • 说明:meta标签在HTML文档中用于向浏览器提供关于如何缓存文档的指令。然而,这些指令并不总是被所有浏览器遵循,因为它们的实现可能因浏览器而异。这些指令通常只影响对HTML文档的缓存决策,而不是文档中包含的资源(如CSS、JavaScript文件或图片)的缓存
  • 对比HTTP的Cache-Control:HTTP响应头中的Cache-Control指令是由服务器发送的,用于精确控制浏览器(以及其他HTTP缓存)对响应的缓存方式。这些指令对于所有类型的资源(HTML文档、CSS、JavaScript、图片等)都有效,由于HTTP响应头是由服务器直接发送给浏览器的,因此这些指令通常具有比HTML文档中的标签更高的优先级。浏览器在决定是否缓存资源时,会优先考虑HTTP响应头中的Cache-Control指令。

8.离线浏览

  • 使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本
  • manifest 的技术已被 web 标准废弃,不再推荐使用此功能

JavaScript 页面缓存的更多相关文章

  1. angular页面缓存与页面刷新

      angularJS学习笔记:页面缓存与页面刷新 遇到的问题 现在存在这样一个问题,登录前与登录成功后是同一个页面,只不过通过ngIf来控制哪部分显示,图像信息如下: 所以,整体工作不是很难,无非就 ...

  2. Flask 页面缓存逻辑,jinja2 过滤器,测试器

    回调接入点-页面缓存逻辑 from flask import Flask,request,render_template from werkzeug.contrib.cache import Simp ...

  3. springboot和redis处理页面缓存

    页面缓存是应对高并发的一个比较常见的方案,当请求页面的时候,会先查询redis缓存中是否存在,若存在则直接从缓存中返回页面,否则会通过代码逻辑去渲染页面,并将渲染后的页面缓存到redis中,然后返回. ...

  4. 设置清除html5页面缓存

    设置清除html5页面缓存 html5端设置 meta 标签: <meta http-equiv="Pragma" content="no-cache" ...

  5. vue中keep-alive,include的指定页面缓存问题

    做vue项目时,有时要在某些页面做缓存,而其它页面不要.比如:A:首页,B:获取所有订单页面,C:订单详情页面:从A(首页)进入 B(获取所有订单)时应该不缓存,B(所有订单)进入 C(订单详情)订单 ...

  6. 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  7. Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

    转载:http://freeloda.blog.51cto.com/2033581/1288553 大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负 ...

  8. cache-contro页面缓存处理设置

    <meta http-equiv="pragma" content="no-cache">,pragma与no-cache用于定义页面缓存,不缓存页 ...

  9. webform的页面缓存

    给页面添加<%@ OutputCache Duration="10" VaryByParam="*"%>标签就可以启用页面缓存. Duration表 ...

  10. 【WP开发】正确理解页面缓存

    注:本文内容面向Runtime App. 在新建项目后,细心观察,你会发现在App类中有以下代码: // TODO: 将此值更改为适合您的应用程序的缓存大小 rootFrame.CacheSize = ...

随机推荐

  1. 商业银行国际结算规模创新高,合合信息AI助力金融行业智能处理多版式文档

    随着我国外贸新业态的快速增长,银行国际结算业务在服务实体经济发展.促进贸易投资便利化进程中发挥了越来越重要的作用.根据中国银行业协会近日发布的<中国贸易金融行业发展报告(2023-2024)&g ...

  2. C++中对象的延迟构造

    本文并不讨论"延迟初始化"或者是"懒加载的单例"那样的东西,本文要讨论的是分配某一类型所需的空间后不对类型进行构造(即对象的lifetime没有开始),更通俗点 ...

  3. MyBatis——案例——环境准备

    配置文件完成增删改查      准备环境     数据库表 tb_brand        -- 创建tb_brand表 create table tb_brand( id int primary k ...

  4. JavaScript中if嵌套assert的方法

    在JavaScript中,通常我们不会直接使用assert这个词,因为JavaScript标准库中并没有直接提供assert函数(尽管在一些测试框架如Jest.Mocha中经常看到).但是,我们可以模 ...

  5. 小米13T Pro系统合集:性能与摄影的极致融合,值得你升级的系统ROM

    小米 13T Pro 是一款性能卓越.设计精美的旗舰机型,具备多项领先配置,且在与前一代产品及友商机型的对比中优势明显,值得深入探讨. 性能提升 小米 13T Pro 搭载了最新的 天玑 9200+ ...

  6. Android UsbDeviceManager 代码分析

    USBDeviceManager是一个Android系统中用于管理USB设备的类,它是系统服务之一.其主要功能是控制USB设备的连接和断开,以及管理USB设备的权限和状态.下面是对USBDeviceM ...

  7. 如何实现高效运维?来谈谈性能优化那些事(含直播回顾 Q&A)

    数据库性能问题,常常是困扰DBA高效运维的难题之一.如何多角度地帮助DBA,找到"数据库慢"的原因,保证系统高效.稳定.安全地运行? 2021年10月14日,云和恩墨技术顾问,拥有 ...

  8. 33. mvvm理解

    MVVM 是module view view-module 数据驱动视图开发模型,是MVC的改进版,采用业务逻辑和页面解构分离的开发思想: MVVM 实现了 view 和 module 的双向绑定,我 ...

  9. 谈一谈 vuex 里边,actions,mutations ,state 之间的运转方式

    首先,调用 actions 中的方法,一般我们在 actions 做登录和登出的请求 : 然后调用 mutations 的方法修改数据 ,因为 mutations 方法是修改state的数据的唯一方法 ...

  10. SpringBoot进阶教程(八十二)Spring Security图形验证码

    在之前的博文<SpringBoot进阶教程(八十)Spring Security>中,已经介绍了在Spring Security中如何基于formLogin认证.基于HttpBasic认证 ...