俄罗斯贵宾会-俄罗斯贵宾会官网
做最好的网站

一篇文章理解Web缓存

一篇文章理解Web缓存

2018/08/09 · 基础技术 · 缓存

原文出处: 这是你的玩具车吗   

最近把前端缓存重新整理了一下,从整体的层面上把前端所有能用的缓存方案梳理了一遍。同时,对于http缓存,使用了表格的方案,使得原先晦涩难记的特性变得清晰明了。特记录于此,若有什么欠缺,也望不吝指出。

时间:2017-03-27 18:02:47

1. 前端缓存概述

前端缓存主要是分为HTTP缓存和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务器代码上设置;而浏览器缓存则主要由前端开发在前端js上进行设置。下面会分别具体描述。

图片 1

该文章为 《HTML5缓存机制浅析:移动端Web加载性能优化》 的读书笔记,整理一下自己的收获。

2. 前端缓存分类

一、HTML5缓存机制介绍

HTML5是新一代的HTML标准,加入很多新的特性。离线存储(也可称为缓存机制)是其中一个非常重要的特性。HTML5引入的离线存储,这意味着Web应用可进行缓存,并可在没有因特网连接时进行访问。

2.1 HTTP缓存

整体流程:HTTP缓存都是从第二次请求开始的。
第一次请求资源时,服务器返回资源,并在respone header头中回传资源的缓存参数;第二次请求时,浏览器判断这些请求参数,击中强缓存就直接200,否则就把请求参数加到request header头中传给服务器,看是否击中协商缓存,击中则返回304,否则服务器会返回新的资源。

HTTP缓存分为强缓存和协议缓存,它们的区别如下:

图片 2

200 from disk or 200 from memory :
强缓存的200也有两种情况:200 from disk和200 from memory。现在我没有找到明确的文档来描述这种区别的发生条件。知乎这个问题中提到了一些情景,可以自行取用。

1.1 HTML5应用程序缓存带来的优势

  1. 离线浏览
  2. 提高加载速度(从缓存中加载)
  3. 减少服务器负载(浏览器将只从服务器下载更新的资源,强缓存的则不发起HTTP请求,协商缓存会发起HTTP,和服务器验证文件是否修改过了)

2.1.1 强缓存

图片 3

1.2 现有的HTML5缓存机制

勾选的,表示熟悉

  • [x] 浏览器缓存机制(强缓存,协商缓存)
  • [x] DOM Storgage 存储机制
  • [ ] Web SQL DataBase 存储机制 【关系型数据库】
  • [ ] Application Cache (App Cache)机制
  • [ ] Indexed DataBase (IndexedDB) 【NoSQL】
  • [ ] File System API

Web SQL DataBase 官方的标准文档不在推荐使用,将来也不再维护,(2015年12月);

  • 各大桌面浏览器和移动端浏览器都有很好的实现这个接口,兼容性问题不大,底层基本都是 sqlite(正因为这样,作为一个web标准是不可接受的)

    • 经测试,IOS上容量最大支持50M,不过用系统自带的safari,超过5MB,会主动提醒用户是否要增加数据库大小,不友好(不过微信里面不会)
    • 5MB 如果用来存一些日志,还是够的(当然需要记得清理旧的日志)
    • websql 目前是主要的解决方案(腾讯用来做日志记录,方便排查用户的错误反馈)
  • Indexed DataBase 是下一代的客服端结构化数据持久存储反感,目前各大浏览器中也有很好的支持,是未来用来替换 websql 的方案。

等下查下最新的情况。

这里只是官网推荐的比较,具体使用还需要看目前业界上的情况。
比如websql目前还是主流的,indexdb是未来用来替换的,具体需要多久,还需要等等。

图片 4

2.1.2 协商缓存

协商缓存都是成对出现的。
图片 5

1.3 目标

  • [ ] 分析各种缓存机制的原理,用法,特点
  • [ ] Android移动端Web性能加载优化
  • [ ] 如何利用缓存机制提高Web加载性能

2.1.3 最佳优化策略-消灭304

最佳优化策略:因为协商缓存本身也有http请求的损耗,所以最佳优化策略是要尽可能的将静态文件存储为较长的时间,多利用强缓存而不是协商缓存,即消灭304。

但是给文件设置一个很长的Cacha-Control也会带来其他的问题,最主要的问题是静态内容更新时,用户不能及时获得更新的内容。这时候就要使用hash的方法对文件进行命名,通过每次更新不同的静态文件名来消除强缓存的影响。

Hash命名:
http://xxx.com/main.5eas34fa.js
http://xxx.com/main.js?5eas34fa
http://xxx.com/5eas34fa/main.js

二、分析各个缓存机制

先对各个缓存机制有一个大体的了解,然后才能去考虑如何优化。目前对 浏览器缓存和DOM Storage比较熟悉,其他的大体了解,但是没有项目中用过。

2.2 浏览器缓存

2.1 浏览器缓存机制

浏览器缓存机制是指通过HTTP协议头里的 Cache-Control / Expires 和 Last-Modified / ETag 等字段控制文件缓存的机制。

和 DOM Storage, AppCache 等缓存机制,本质一样。 一个在HTTP协议层实现(浏览器缓存),一个在应用层实现。

2.2.1 本地存储小容量

Cookie主要用于用户信息的存储,Cookie的内容可以自动在请求的时候被传递给服务器。
LocalStorage的数据将一直保存在浏览器内,直到用户清除浏览器缓存数据为止。
SessionStorage的其他属性同LocalStorage,只不过它的生命周期同标签页的生命周期,当标签页被关闭时,SessionStorage也会被清除。

图片 6

2.1.1 强缓存

采用 Cache-Control 和 Expires 来控制缓存。 Chrome开发者工具NetWork, 查看为 form disk cache

图片 7

  • Cache-Control (HTTP1.1标准中新增的字段)

    1. 控制文件本地缓存的有效时间.
    2. Cache-Control:max-age=600 表示文件本地缓存有效时间600s,接下来600s内请求这个资源,浏览器不发出HTTP请求,直接从本地缓存拿
    3. 是一个相对的时间
  • Expires (HTTP1.0标准中的字段)
    1. Expires: Thu, 10 Nov 2015 08:45:11 GMT 表示在这个时间前,缓存有效
    2. 是一个绝对时间,由于服务器的时间和客服端的时间可能不一致造成缓存问题,因此引入了HTTP1.1的Cache-Control
    3. 优先级小于 Cache-Control

2.2.2 本地存储大容量

WebSql和IndexDB主要用在前端有大容量存储需求的页面上,例如,在线编辑浏览器或者网页邮箱。

图片 8

2.1.2 协商缓存

HTTP 的状态为 304 表示 协商缓存

图片 9

  • Last-Modified 和 If-Modified-Since

    Last-Modified是标识文件在服务器上的最新更新时间。下次请求时,如果文件缓存过期,浏览器通过If-Modified-Since字段带上这个时间,发送给服务器,由服务器比较时间戳来判断文件是否有修改。如果没有修改,服务器返回304告诉浏览器继续使用缓存;如果有修改,则返回200,同时返回最新的文件。

  • ETag 和 If-None-Match

    Etag也是和Last-Modified一样,对文件进行标识的字段。不同的是,Etag的取值是一个对文件进行标识的特征字串。在向服务器查询文件是否有更新时,浏览器通过If-None-Match字段把特征字串发送给服务器,由服务器和文件最新特征字串进行匹配,来判断文件是否有更新。没有更新回包304,有更新回包200。

Etag和Last-Modified可根据需求使用一个或两个同时使用。两个同时使用时,只要满足基中一个条件,就认为文件没有更新。

2.2.3 应用缓存与PWA

应用缓存全称为Offline Web Application,它的缓存内容被存在浏览器的Application Cache中。它也是一个被W3C标准废弃的功能,主要是通过manifest文件来标注要被缓存的静态文件清单。但是在缓存静态文件的同时,也会默认缓存html文件。这导致页面的更新只能通过manifest文件中的版本号来决定。而且,即使我们更新了version,用户的第一次访问还是会访问到老的页面,只有下一次再访问才能访问到新的页面。所以,应用缓存只适合那种常年不变化的静态网站。如此的不方便,也是被废弃的重要原因。

PWA全称是渐进式网络应用,主要目标是实现web网站的APP式功能和展示。尽管PWA也有manifest文件,但是与应用缓存却完全不同。不同于manifest简单的将文件通过是否缓存进行分类,PWA用manifest构建了自己的APP骨架。另外,PWA用Service Worker来控制缓存的使用。这一块的内容较多,在这里就不详细展开了。

图片 10

2.1.3 F5 和 Ctrl+F5 的特殊情况

手动刷新页面(F5),浏览器会直接认为缓存已经过期(可能缓存还没有过期),在请求中加上字段:Cache-Control:max-age=0,发包向服务器查询是否有文件是否有更新。

可能存在304协商缓存

强制刷新页面(Ctrl+F5),浏览器会直接忽略本地的缓存(有缓存也会认为本地没有缓存),在请求中加上字段:Cache-Control:no-cache(或 Pragma:no-cache),发包向服务重新拉取文件。

不存在强缓存和协商缓存

2.2.4 往返缓存

往返缓存又称为BFCache,是浏览器在前进后退按钮上为了提升历史页面的渲染速度的一种策略。BFCache会缓存所有的DOM结构,但是问题在于,一些页面开始时进行的上报或者请求可能会被影响。这个问题现在主要会出现在微信h5的开发中

去除BFCache有多种方法,但不是本文的重点,想了解的同学可以看《浏览器往返缓存(Back/Forward cache)问题的分析与解决

三、LocalStorage, SessionStorage

一个简单的键值对存储系统,接口简单实用,兼容性也很好。有大小限制,提供5M(不同浏览器可能不同,区分host, cookie 只有 4k)

总结

本文梳理了前端所有可能涉及的缓存,希望能从整体层面建立起系统的缓存知识体系。限于篇幅,每一部分的描述都比较简略,仅起到抛砖引玉之用。如有错误,还望指出。

1 赞 收藏 评论

图片 11

3.1 LocalStorage和 SessionStorage的用法

interface Storage { 

    readonly attribute unsigned long length;

    [IndexGetter] DOMString key(in unsigned long index); 

    [NameGetter] DOMString getItem(in DOMString key); 

    [NameSetter] void setItem(in DOMString key, in DOMString data); 

    [NameDeleter] void removeItem(in DOMString key); 

    void clear();
};

3.2 LocalStorage 和 SessionStorage 的区别

LocalStorage 和 SessionStorage 的区别, SessionStorage 在页面选项卡关闭后,就不存在了, 但是 LocalStorage会还存在。但是注意:页面刷新的时候,SessionStorage还是存在的。

比如在 页面刷新后,表单填写的内容还存在,这个时候使用 SessionStorage最有用了。

本文由俄罗斯贵宾会发布于Web前端,转载请注明出处:一篇文章理解Web缓存

您可能还会对下面的文章感兴趣: