前端缓存总结

269 阅读14分钟

1,http缓存

简介:

    http缓存存在于浏览器与服务器之间,通过http请求头和响应头的相关值来判断用户获取一个资源是从缓存中获取还是从服务器中来获取.
    http缓存从本地获取资源,减少了请求次数,从而实现了资源的快速响应,服务器压力减小以及减小带宽的目的.但同时也增加了内存的使用。

分类:
强缓存:expires(HTTP/1.0),cache-control(HTTP/1.1)
协商缓存:Etag/if-none-match(HTTP/1.1), Last-modified/if-modified-since((HTTP/1.0))

执行流程:
浏览器在第一次请求后缓存资源,再次请求时,会进行下面两个步骤:

  1. 浏览器会获取该缓存资源的 header 中的信息,根据 response header 中的 expires 和 cache-control 来判断是否命中强缓存,如果命中则直接从缓存中获取资源。
  2. 如果没有命中强缓存,浏览器就会发送请求到服务器,这次请求会带上 IF-Modified-Since 或者 IF-None-Match, 它们的值分别是第一次请求返回 Last-Modified或者 Etag,由服务器来对比这一对字段来判断是否命中。如果命中,则服务器返回 304 状态码,并且不会返回资源内容,浏览器会直接从缓存获取;否则服务器返回200,并更新 资源以及response header 中的相关缓存字段。

在强缓存中,cache-control优先级高于Expires,协商缓存中Etag的优先级高于last-Modified

image.png

如何开启缓存:

  1. 配置Tomact或者ngix服务器,开启相应缓存模块
  2. 后端代码中动态设置
  3. 前端HTML页面meta标签

2,浏览器缓存

浏览器缓存分类:

  1. 本地小容量缓存:cookie、localstorage、sessionStorage
    (localStorage和sessionStorage统称为webStorage)
  2. 本地大容量缓存:indexDB,websql
  3. 其他缓存:application cache

cookie

cookie指的就是会话跟踪技术。主要由服务器设置保存在本地的数据,当浏览器再次请求的时候,浏览器会自动携带相对应的cookie给服务器,服务器拿到对应的cookie可以对用户进行识别。

cookie的典型应用(用户登录):

  1. 用户第一次登录输入用户密码,服务器拿到数据检验通过之后,会分配一个session,并生成一个随机的sessionId,这个并生成一个随机的sessionId作为key,用户的身份信息作为value,通过setCookie返回。
  2. 浏览器拿到对应的cookie数据会缓存起来
  3. 再次访问服务器的时候,会自动带上相应的cookie数据,服务器拿到cookie与session中数据对比,即可查看到用户登录的相关信息。

image.png

cookie主要特点有:

1、cookie不可跨域  
2、cookie存储在浏览器里面  
3、cookie有数量与大小的限制,数量在50个左右,存储大小在4K以内
4、cookie不光可以服务器设置(用set-cookie),也可以客户端设置。
5、cookie可以设置有效期,超出有效期自动清除。
6、cookie只能存储字符串类型。

cookie常用操作:

setMaxAge - 设置cookie的有效期,时间单位是秒,负值时表示关闭浏览器后就失效,默认值为-1。
setDomain - 用于指定,只有请求指定域名才会带上该cookie。
setPath - 只有访问该域名下的cookieDemo的这个路径地址才会带cookie。
setValue - 重置 value 。

cookie详解

localstorage

localStorage 是HTML5的一种新的本地缓存方案,目前使用比较多,一般存储ajax返回的数据,

存储特点主要有:

  • 数据可以长久保存,没有有效期,直到手动删除为止。
  • 存储的数据量大,一般5M以内。
  • 存储的数据可以在同一个浏览器的多个窗口使用。
  • 存储的数据不会发送到服务器。

localStroage常用API如下:

1.  localStorage.setItem(key,value) // 保存数据
2.  localStorage.getItem(key) // 获取数据
3.  localStorage.removeItem(key) // 删除单个数据
4.  localStorage.clear() // 删除全部

sessionstorage

sessionStorage与上述localStroage类似,

它的特点主要有:

  • 存储的数据在浏览器关闭后删除,与网页窗口具有相同的生命周期。
  • 可以存储的数据大小5M。
  • 存储的数据不会发送到服务器。

sessionStorage常用API如下:

sessionStorage.setItem(key,value) // 保存数据
sessionStorage.getItem(key) // 获取数据
sessionStorage.removeItem(key) // 删除单个数据
sessionStorage.clear() // 删除全部

sessionStorage的清除时机是在会话结束,会话结束是在用户关闭标签页或者关闭窗口的时候;手动新开一个标签或窗口时,会新开会话,即使链接一样,也不会共享sessionStorage

只有在下面情况1的时候,新开页面才能'共享'sessionStorage

1. 场景1:如果用户在A页面下存储了test,通过js或者a标签跳转到**同源**的B页面时,A页面sessionStorage
会被拷贝到B页面下,AB页面的sessionStorage虽然相同,但二者相互独立;另外如果用户在A页面下存储了test,
通过js或者a标签跳转到**不同源**的B页面时,尽管还是在同一标签页下,但是在B页面获取不到test项。

2. 场景2:如果用户在A页面打开的情况下,手动打开了一个新标签页,访问A页面,此时会重开一个新回话,二者
sessionStorage是不共享的。

因此sessionStorage 和 localStorage 的主要区别在于他们存储数据的生命周期:
sessionStorage 存储的数据的生命周期是一个会话, 而 localStorage存储的数据的生命周期是永久 除非主动删除数据,否则永远不会过期

image.png

websql

websql是较新的chrome浏览器支持,并以独立规范形式出现,引入了一组使用 SQL 操作客户端数据库的 APIs。
websql主要特点:

  • Web Sql数据库 API 不是HTML5的一部分,在H5之前就已经存在了。
  • 将数据以数据库的形式存储在客户端,按需读取。
  • 数据便于检索,允许使用sql语句。
  • 可以使浏览器实现小型数据库存储功能。

常用的api如下:

1.  openDatabase - 打开已存在的数据库,如果不存在,则会新建一个新的数据库。
2.  transaction - 控制一个事物,以及这种情况执行提交或者回滚。
3.  executeSql - 执行 SQL 语句。

websql基本使用

web sql被废弃

  1. 缺乏支持:各大浏览器对web sql的兼容性并不是很好
  2. 性能问题:在大型数据集上执行的查询可能会变得非常缓慢,需要大量数据加载到dom上,进而导致性能问题。
  3. 安全问题:非常容易成为攻击者利用的目标,并可能带来安全隐患。

尽管web sql已经被废弃,我们仍然可以学到可以以一种执行sql的方式来存储结构化的数据,将来技术迭代,或许也有可能解决这些问题。

indexDB

随着浏览器的功能不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据。

通俗地讲,IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。

indexDB 是为了能够在客户端存储客观数量的结构化数据,并且在这些数据上使用索引进行高性能的检索。DOM存储对于少量数据是非常友好的,但不适合存储大量结构化数据,indexDB就是为了解决这个问题而生的。

indexDB 分别为同步和异步访问提供了单独的API,同步API本打算供Web Worker内部使用,但目前还未实现。异步API在Web Worker内部和外部都可以使用,另外浏览器对indexDB有50M大小限制。

indexDB使用场景:

indexDB是一个浏览器使用简易的数据库。随着前端功能复杂度提升,用户需要多元化,前端indexDB应用也就越来越多。桌面应用、Progressive Web App(PWA)、chrome扩展组件的开发等。用户同时会获取/操作更多的信息,怎么留存这些大量的数据,那么我们的indexDB就上线了。 案例:DevDocs,electron开发的桌面应用(图片传输)

indexDB主要特点有:

indexDB大小取决于你的硬盘,存储的数据量非常大。
可以直接存储任何类型的数据,如 js任何类型的数据 、blob流。
可以创建索引,提供高性能搜索功能。
采用事务,保证数据的准确性和一致性。

indexDB操作步骤:

  1. 创建/打开数据库。
  2. 在数据库中创建一个对象仓库(object store)。
  3. 启动一个事务,并发送一个请求来执行一些数据库操作,像增加或提取数据等。
  4. 通过监听正确类型的 DOM 事件以等待操作完成。
  5. 在操作结果上进行一些操作(可以在 request 对象中找到)

IndexDB具体使用案例

indexDB和web sql区别

indexDBwebsql说明
数据格式增强型的 Web Storage,是一种存储key-value类型的非关系数据库(NoSQL)。是SQLite在浏览器中的实现,所以它是一种关系型数据库。如果存储简单的key-value,可以选择webStorage即可和indexDb,如果存储较为复杂的数据结构,则可以使用websql
存储容量是没有存储上限的一般来说不会小于 250M,最大存储容量取决于两个因素,浏览器和磁盘空间。大小默认是50M,当超过时浏览器会弹出是否允许扩容提示,每次可扩容5M
兼容性问题兼容性挺好存在兼容性问题,ie和火狐均不支持

application cache

application cache是离线缓存技术,将大部分的图片、js、css等资源放在mainfest文件配置中,页面打开时通过mainfest文件读取本地文件或请求服务器资源。通常用于静态页面的缓存(这不同于之前讲的一些浏览器缓存,webStorage,indexDB,webSql只是对相关数据的缓存,而application cache则是对页面以及其他静态资源进行缓存)。

application cache的使用

1,首先需要有一个manifest文件,是用来配置对应文件资源缓存情况的一个清单 在缓存清单文件的部分:CACHE,NETWORK,和FALLBACK


CACHE MANIFEST

CACHE:
# v1 2011-08-14
# This is another comment
index.html
cache.html
style.css
image1.png

# Use from network if available
NETWORK:
network.html

# Fallback content
FALLBACK:
/ fallback.htm
//此示例使用NETWORK和FALLBACK部分指定network.html页面必须始终从网络检索,并且fallback.html页面应作为后备资源(例如,如果无法建立与服务器的连接)。
  1. CACHE:这是缓存清单文件中条目的默认部分。第一次下载文件之后,列出CACHE:部分标题下的文件(或紧后CACHE MANIFEST)。
  2. NETWORK:NETWORK:缓存清单文件中的部分标题下列出的文件是需要连接到服务器的白名单资源。即使用户离线,对这种资源的所有请求都绕过缓存。通配符可以使用一次。大多数网站需要。
  3. FALLBACK:该FALLBACK:部分指定浏览器在资源不可访问时应使用的后备页面。本节中的每个条目都列出了两个URI:第一个是资源,第二个是后备。这两个URI必须是与清单文件相对的和与源文件相同的来源。可以使用通配符的CACHE,NETWORK和FALLBACK 部分可以在高速缓存中的清单文件的任何顺序排列,并且各部分可以在单一清单中出现一次以上。

2,在HTML中引入.manifest文件,可以使用应用缓存了。

application cache的缓存文档加载和更新流程:

  • 当浏览器访问一个包含manifiest特性的文档时,如果应用缓存不存在,浏览器会加载文档,然后获取在清单文件中列出的文件,生成应用缓存的第一个版本。
  • 后续再次访问时,浏览器直接从应用缓存(而不是服务器)加载文档与其他在清单文件中列出的资源。同时,浏览器还会向window.applicationCache对象发送一个checking事件,在遵循合适的http缓存规则前提下,获取清单文件
  • 把上面提到的checking事件后获取到的服务端的文件清单和当前浏览器缓存的清单副本对比,如果当前浏览器的清单副本时最新的,浏览器将向application对象发送一恶搞noupdate事件,到此更新过程结束。
  • 如果清单文件已经改变,文件列出的所有文件会被放到一个临时缓存中,遵循适当的http规则,对于每个加入到临时缓存中的文件,浏览器会向application对象发送一个progress事件。如果出现任何错误,浏览器会发送一个error事件,并暂停更新。
  • 一旦所有文件都获取成功,他们会自动移送到真正的离线缓存中,并向appilcation对象发送一个cached事件。鉴于文档早已经被从缓存加载到浏览器中,所以更新后的文档不会重新渲染,直到页面重新加载(可以手动或通过程序)这里特别注意一下,当你在服务器端修改了文件同时也更新了清单文件,刷新页面却没有显示我们的修改,这并没有错误,好好理解前面那句说明,你要想看到你的修改,可以简单的再刷新一次。

application cache特点:

  • mainfest文件必须有变化时才会更新。
  • 一次必须更新mainfest文件中的所有文件才能生效。
  • 当网络断开时,可以继续访问页面。
  • 文件缓存到本地,不需要每次都从网络上请求。
  • 稳定性比较好,遇网络故障或服务器故障可以继续访问本地缓存。
  • 加载速度快,缓存资源为本地资源,因此加载速度较快。

由于lication cache本身存在一些问题,如无法动态更新缓存,缓存容量有限等,所以组件被service worker替代

3,cache Storage

cacheStorage 表示 cache对象的存储。 该接口提供 serviceWorker 或其他类型的工作线程或window范围访问的所有命名缓存的主目录。

特点:

  • Cache Stroage只能缓存静态资源,所以它只能缓存用户的 GET 请求
  • Cache Stroage中的缓存不会过期,但是浏览器对它的大小是有限制的,所以需要我们定期进行清理
  • CacheStorage 总是对不受信任的源(即那些不使用HTTPS)使用 SecurityError reject. 在Firefox Devtools选项/齿轮菜单中通过选中"通过HTTP启用 Service Workers (当工具箱打开时)" 选项来绕开这个限制

CacheStorage常见方法:

  • CacheStorage.match() - 检查给定的 Request 对象是否是 CacheStorage 对象跟踪的 Cache 对象中的键,返回Promise
  • CacheStorage.has() - 返回一个 Promise,它解析为与 cacheName 相匹配的 Cache 对象。
  • CacheStorage.delete() - 删除cache对象
  • CacheStorage.keys() - 含有keys中字符串的任意一个,则返回一个promise对象。
  • cacheStorage.has() - 如果包含cache对象,则返回一个promise对象。

4,flash缓存

flash缓存也是页面通过js调用flash读写特定的磁盘目录,达到本地数据缓存的目的。这是要基于flash的,所以基本不用。