http请求作为影响前端性能极为重要的一环,由于请求受网络影响很大,若是网络很慢的状况下,页面极可能会空白好久。对于首次进入网站的用户可能要经过优化接口性能和接口数量来解决。可是,对于重复进入页面的用户,除了浏览器缓存,http缓存能够很大程度对已经加载过的页面进行优化。css
从缓存位置上来看,分为4种,从上往下依次检查是否命中,若是但都没有命中则从新发起请求。
Service Worker 是运行在浏览器背后的独立线程,通常能够用来实现缓存功能。使用 Service Worker的话,传输协议必须为 HTTPS。
Memory Cache 也就是内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据确定比磁盘快,内存缓存虽然读取高效,但是缓存持续性很短,会随着进程的释放而释放。 一旦咱们关闭 Tab 页面,内存中的缓存也就被释放了。
内存缓存中有一块重要的缓存资源是preloader相关指令(例如<link rel="prefetch">)下载的资源。它能够一边解析js/css文件,一边网络请求下一个资源。
Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,可是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。
绝大部分的缓存都来自Disk Cache,在HTTP 的协议头中设置。
Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,一旦会话结束就被释放,而且缓存时间也很短暂,在Chrome浏览器中只有5分钟左右,同时它也并不是严格执行HTTP头中的缓存指令。html
下面主要说一下前端优化能入手的地方,也就是强缓存和协商缓存,而且缓存策略都是经过设置 HTTP Header 来实现的。前端
浏览器在第一次访问接口后的response headers里会携带一些字段,这些字段决定关于这个请求的缓存状况,
与强缓存相关的header字段有两个:html5
一、expires:过气网红,这是http1.0时的规范;它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT,若是发送请求的时间在expires以前,那么本地缓存始终有效,不然就会发送请求到服务器来获取资源web
二、cache-control:新星:max-age=number,这是http1.1时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对值;资源第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过时时间,再拿这个过时时间跟当前的请求时间比较,若是请求时间在过时时间以前,就能命中缓存,不然就不行;
no-cache:不使用本地缓存。须要使用协商缓存,先与服务器确认返回的响应是否被更改,若是以前的响应中存在ETag,那么请求的时候会与服务端验证,若是资源未被更改,则能够避免从新下载。数据库
no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。浏览器
public:能够被全部的用户缓存,包括终端用户和CDN等中间代理服务器。缓存
private:只能被终端用户的浏览器缓存,不容许CDN等中继缓存服务器对其缓存。
注意:若是cache-control与expires同时存在的话,cache-control的优先级高于expires安全
强缓存时段命中,会直接从缓存中返回数据,返回值200;这一时间段,无论接口内容有没有变化都不会进行请求更新。服务器
当没有强缓存时,会向服务端寻求帮助,也就是问一下服务端有没有更改,向接口判断是否有缓存。若是命中协商缓存则返回304状态码,而且从本地返回缓存内容。若是没有命中,则从新发起请求。
协商缓存须要跟服务端经过特殊标示链接,即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段。
具体过程以下:
Last-Modified/If-Modified-Since
1.浏览器第一次跟服务器请求一个资源,respone的header里加上Last-Modified:表示这个资源在服务器上的最后修改时间
2.浏览器再次跟服务器请求这个资源时,在request的header上加上If-Modified-Since的header:上一次请求时返回的Last-Modified的值
3.服务器再次收到资源请求时,会判断最后修改时间是否有变化,若是没有变化则返回304 Not Modified,可是不会返回资源内容;若是有变化,就正常返回资源内容,Last-Modified会被修改成最新的值。若是没有变化,服务器返回304 Not Modified,Last-Modified不会修改,response header中不会再添加Last-Modified的header
4.浏览器收到304的响应后,就会从缓存中加载资源
Etag/If-None-Match
由服务器生成的每一个资源的惟一标识字符串,只要资源有变化就这个值就会改变;其判断过程与Last-Modified/If-Modified-Since相似,与Last-Modified不同的是,当服务器返回304 Not Modified的响应时,因为ETag从新生成过,response header中还会把这个ETag返回,即便这个ETag跟以前的没有变化。
1.一些文件也许会周期性的更改,可是他的内容并不改变(仅仅改变的修改时间),这个时候咱们并不但愿客户端认为这个文件被修改了,而从新GET;
2.某些文件修改很是频繁,好比在秒如下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改没法判断(或者说UNIX记录MTIME只能精确到秒);
3.某些服务器不能精确的获得文件的最后修改时间。
Last-Modified与ETag是能够一块儿使用的,服务器会优先验证ETag,一致的状况下,才会继续比对Last-Modified,最后才决定是否返回304。
浏览器本地缓存最经常使用的是cookie、localStroage、sessionStroage、webSql、indexDB。
cookie的用法很简单,能够经过服务端设置,js也能够经过documnet.cookie="名称=值;"(不要忘记以;分割)来设置。
cookie的值字符串能够用encodeURIComponent()来保证它不包含任何逗号、分号或空格(cookie值中禁止使用这些值).
cookie通常用作为登录态保存、密码、我的信息等关键信息保存使用,因此为了安全也是遵照同源策略原则的。
能够经过下面参数具体设置:
;path=path (例如 '/', '/mydir') 若是没有定义,默认为当前文档位置的路径。
;domain=domain (例如 'example.com', 'subdomain.example.com') 若是没有定义,默认为当前文档位置的路径的域名部分。与早期规范相反的是,在域名前面加 . 符将会被忽视,由于浏览器也许会拒绝设置这样的cookie。若是指定了一个域,那么子域也包含在内。
;max-age=max-age-in-seconds (例如一年为606024*365)
;expires=date-in-GMTString-format 若是没有定义,cookie会在对话结束时过时这个值的格式参见Date.toUTCString()
;secure (cookie只经过https协议传输)
;HttpOnly 限制web页面程序的browser端script程序读取cookie
缺点
容量有限制,不能超过4kb
在请求头上带着数据安全性差
html5新增本地存储,localStorage生命周期是永久,除非主动清除localStorage信息,不然这些信息将永远存在。存放数据大小为通常为5MB,sessionStorage仅在当前会话下有效,关闭页面或浏览器后被清除。并且它仅在客户端(即浏览器)中保存,不参与和服务器的通讯。也是遵照同源策略原则的
// 一、保存数据到本地 // 第一个参数是保存的变量名,第二个是赋给变量的值 localStorage.setItem('key', 'value'); //复杂类型储存须要**利用JSON.stringify**将对象转换成字符串; //利用**JSON.parse**将字符串转换成对象 // 二、从本地存储获取数据 localStorage.getItem('key'); // 三、从本地存储删除某个已保存的数据 localStorage.removeItem('key'); // 四、清除全部保存的数据 localStorage.clear();
WebSQL是前端的一个独立模块,是web存储方式的一种,咱们调试的时候会常常看到,只是通常不多使用。而且,当前只有谷歌支持,ie和火狐均不支持。
主要方法:
1.openDatabase:这个方法使用现有的数据库或者新建的数据库建立一个数据库对象。
2.transaction:这个方法让咱们可以控制一个事务,以及基于这种状况执行提交或者回滚。
3.executeSql:这个方法用于执行实际的 SQL 查询。
IndexedDB 就是浏览器提供的本地数据库,它能够被网页脚本建立和操做。IndexedDB 容许储存大量数据,提供查找接口,还能创建索引。这些都是 LocalStorage 所不具有的。就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。
具体概念参考:参考文章