Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

缓存 #27

Open
oliver1204 opened this issue Mar 13, 2017 · 0 comments
Open

缓存 #27

oliver1204 opened this issue Mar 13, 2017 · 0 comments

Comments

@oliver1204
Copy link
Owner

oliver1204 commented Mar 13, 2017

1、浏览器缓存机制

2、Dom Storgage(Web Storage)

3、Web SQL Database 存储机制(不再维护,被5取代了

4、Application Cache(manifest)(不再维护

5、Indexed Database (IndexedDB)

6、File System API

1. Dom Storgage(Web Storage)存储机制

1.1 cookies(4KB)

由于http 1.0是无状态的,在发起网络请求时,发送第一个请求和第二个请求时浏览器是不知道他们之间的关系的。所以我们目前来说通常是利用 cookie 来记录一些信息。

当浏览器加载 HTML 文件中引用的静态资源 —— 如图片、外部 CSS、外部 JS 等时,若该资源所属域与当前页面相同,则会在 HTTP 头请求中加载当前域的 cookie 信息。

换句话说,如果一个页面上有50张图片,即使一个 cookie 1KB,但是如果你要加载 50 个图片(或其它静态文件),这样发送的 cookie 总量就多达 50KB 了。

这也就是为什么我之前很多人很喜欢把 cdn 域名划到主域外,这样就减少了cookie 等不必要的数据量。或者合并请求、启用 Cookie-Free 域名。但http2 就没有必要担心了,http2做了首部压缩。
补充http2的内容

1.2 sessionStorage

通过存储字符串的 Key/Value 对来提供的,并提供 `5MB `(不同浏览器可能不同,分 HOST)的存储空间。不像 Cookies,每次请求一次页面,Cookies 都会发送给服务器。

sessionStorage 用来存储与页面相关的数据,它在页面关闭后无法使用。

1.3 localStorage

localStorage 则持久存在,在页面关闭后也可以使用

2. Indexed Database (IndexedDB)

IndexedDB 也是一种数据库的存储机制,但又不是传统的关系数据库,可归为 SQL 数据库。IndexedDB 类似于 Dom Storage 的 key-value 的存储方式,但功能更强大,且存储空间更大。

IndexedDB 中Key 是必需,且要唯一;Key 可以自己定义,也可由系统自动生成。Value 也是必需的,但 Value 非常灵活,可以是任何类型的对象。一般 Value 都是通过 Key 来存取的。

IndexedDB 提供了一组 API,可以进行数据存、取以及遍历。这些 API 都是异步的,操作的结果都是在回调中返回。

API

3. File System API

API

使用

File System API 是 H5 新加入的存储机制。它为 Web App 提供了一个虚拟的文件系统,就像 Native App 访问本地文件系统一样。Web App 在虚拟的文件系统中,可以进行文件(夹)的创建、读、写、删除、遍历等操作。

优势:

  • 可以满足大块的二进制数据( large binary blobs)存储需求。
  • 可以通过预加载资源文件来提高性能。
  • 可以直接编辑文件。
  • 浏览器给虚拟文件系统提供了两种类型的存储空间:临时的和持久性的。

临时的存储空间是由浏览器自动分配的,但可能被浏览器回收;
持久性的存储空间需要显示的申请,申请时浏览器会给用户一提示,需要用户进行确认。
持久性的存储空间是 WebApp 自己管理,浏览器不会回收,也不会清除内容。持久性的存储空间大小是通过配额来管理的,首次申请时会一个初始的配额,配额用完需要再次申请。

虚拟的文件系统是运行在沙盒中。不同 WebApp 的虚拟文件系统是互相隔离的,虚拟文件系统与本地文件系统也是互相隔离的。

网络应用可通过调用 window.requestFileSystem() 请求对沙盒文件系统的访问权限

蓝图

• 有上传器的应用

◦	当你选择一个文件或目录进行上传时,你可以赋值文件到一个本地沙盒并一次上传一个块。

◦	应用可以在一次中断后重新上传,中断可能包括浏览器被关闭或崩溃,连接中断,或电脑被关闭。

• 视频游戏或其他使用大压缩包并在本地将他们解压到一个文件目录中。

◦	应用能在后台预取资源,从而让用户能够进入下一项工作或游戏等级,而不需要等待下载。

• 音频或照片编辑器使用线下访问或本地缓存(有助于表现和速度)

◦	应用可以分段写入文件(例如只覆盖ID3/EXIF标签而不是整个文件)。

• 线下视频浏览

◦	应用可以下载大文件(>1GB)用于以后浏览。

◦	应用可以访问只下载了部分的文件(因此你可以查看你的DVD的第一章,即使应用仍在下载剩余部分,或者当你需要取赶火车而没有完成下载时)。

• 线下网络邮件客户端

◦	客户端下载附件并在本地存储它们。
◦	客户端缓存附件用于稍后的上传。

4. 浏览器缓存(HTTP协议定义的缓存机制)

缓存分很多种:服务器缓存,第三方缓存,浏览器缓存等。其中浏览器缓存是代价最小的,因为浏览器缓存依赖的是客户端,而几乎不耗费服务器端的资源。

我们先在chrome浏览器下看看到底缓存了什么东西

查看所有的缓存文件

随便点开一个,可以看到这个缓存文件所有的信息,包括访问url,http请求的头信息,和缓存文件正文内容

image

4.1 浏览器缓存类型

有两种,强缓存协商缓存

1.强缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的network选项中可以看到该请求返回200的状态码,并且size显示from disk cache或from memory cache;

2.协商缓存:向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;

4.2 浏览器缓存过程

  1. 浏览器第一次加载资源,服务器返回200,浏览器将资源文件从服务器上请求下载下来,并把response header及该请求的返回时间一并缓存;

  2. 下一次加载资源时,先比较当前时间和上一次返回200时的时间差,如果没有超过cache-control设置的max-age,则没有过期,命中强缓存,不发请求直接从本地缓存读取该文件(如果浏览器不支持HTTP1.1,则用expires判断是否过期);如果时间过期,则向服务器发送header带有If-None-Match和If-Modified-Since的请求;

  3. 服务器收到请求后,优先根据Etag的值判断被请求的文件有没有做修改,Etag值一致则没有修改,命中协商缓存,返回304;如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200;

  4. 如果服务器收到的请求没有Etag值,则将If-Modified-Since和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回304;不一致则返回新的last-modified和文件并返回200;

4.3 缓存有关的header

4.3.1 Expires(http 1.0) & Cache-Control(http 1.1) (强缓存)

Expires(http 1.0)

image

 
优点:Expires属性告诉浏览器相关副本可以保存在缓存器中的时间。在此时间内,浏览器在访问相关内容的时候,不发任何请求

缺点:

  • 是牵扯到了日期,这样Web服务器的时间和缓存服务器的时间必须是同步的,如果有些不同步, 要么是应该缓存的内容提前过期了,要么是过期结果没及时更新。

  • 如果在固定时间前服务器更新了内容浏览器并不知道(此时,刷新会请求,地址栏敲回车【模拟新开webview】不会请求 )。

  • 过期时间头信息属性值只能是HTTP格式的日期时间,其他的都会被解析成当前时间“之前”,副本会过期,记住:HTTP的日期时间必须是**格林威治时* 间(GMT),而不是本地时间。举例:Expires: Fri, 30 Oct 1998 14:19:41

Cache-Control(http 1.1)

  • max-age=[秒] — 缓存被保留的最长时间。
  • s-maxage=[秒] — 类似于max-age属性,除了他应用于共享(如:代理服务器)缓存
  • public — 表示响应可以被任何缓存区缓存。
  • private - 表示对于单个用户的响应,不能被共享缓存处理。私有的缓存区可以存储
  • no-cache — 强制每次请求直接发送给源服务器,而不经过本地缓存版本的校验。这对于需要确认认证应用很有用(可以和public结合使用),或者严格要求使用最新数据的应用(不惜牺牲使用缓存的所有好处);
    2* no-store — 强制缓存在任何情况下都不要保留任何副本
  • must-revalidate — 缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。
  • proxy-revalidate — 和 must-revalidate类似,除了他只对缓存代理服务器起作用

例:Cache-Control: max-age=3600, must-revalidate

Expires和Cache-Control:max-age=*** 的作用是差不多的,区别就在于 Expires 是http1.0的产物,Cache-Control是http1.1的产物,两者同时存在的话,Cache-Control优先级高于Expires;在某些不支持HTTP1.1的环境下,Expires就会发挥用处。所以Expires其实是过时的产物,现阶段它的存在只是一种兼容性的写法
Expires和Cache-Control的区别还有一个:Expires是一个具体的服务器时间,这就导致一个问题,如果客户端时间和服务器时间相差较大,缓存命中与否就不是开发者所期望的。Cache-Control是一个时间段,控制就比较容易。

4.3.2 ETag & If-None-Match & Last-Modified (协商缓存)

image

image

Etag是上一次加载资源时,服务器返回的response header,是对该资源的一种唯一标识,只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器接受到If-None-Match的值后,会拿来跟该资源文件的Etag值做比较,如果相同,则表示资源文件没有发生改变,命中协商缓存。

Last-Modified和If-Modified-Since:这两个也要一起说。Last-Modified是该资源文件最后一次更改时间,服务器会在response header里返回,同时浏览器会将这个值保存起来,在下一次发送请求时,放到request header里的If-Modified-Since里,服务器在接收到后也会做比对,如果相同则命中协商缓存。

ETag和Last-Modified的作用和用法也是差不多,说一说他们的区别。
首先在精确度上,Etag要优于Last-Modified。Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度;如果是负载均衡的服务器,各个服务器生成的Last-Modified也有可能不一致。

第二在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。

第三在优先级上,服务器校验优先考虑Etag。

用户行为对浏览器缓存的控制

地址栏访问,链接跳转是正常用户行为,将会触发浏览器缓存机制;

F5刷新,浏览器会设置max-age=0,跳过强缓存判断,会进行协商缓存判断;

ctrl+F5刷新,跳过强缓存和协商缓存,直接从服务器拉取资源。

4.5 其他

Date:Date头域表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date: Mon, 04 Jul 2011 05:53:36 GMT。
Age:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。

@oliver1204 oliver1204 changed the title manifest 专场 缓存 Jul 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant