前端面试之4-3 页面性能(协商缓存绕晕了)

前端面试之4-3 页面性能(协商缓存绕晕了)_第1张图片

第二个是层层递进地问。

第三个,缓存才是最重要的一步。浏览器缓存和LocalStorage,sessionstorage存储,不是一回事。说出来缓存分类,还会问你缓存原理。

第四个,CDN,网络优化这一方面。比如使用n个图片,怎么让用户最快请求得到?除了变小,最重要使用CDN,尤其是第一打开页面,提升速度,缓存是起不了任何作用的。CDN效果是明显的。

第五个,把第二句话,从输入url地址到页面渲染完,中间发生了哪些环节?其中第一步做的就是DNS解析。在提升页面性能,尤其是你页面涉及多个域名时候,dns解析是效果明显的。这里优化的点,就是预解析DNS,怎么预解析?就是把上面第二句话,放在head里面。那么第一句话什么意思?页面中所有a标签默认打开DNS预解析的。但是页面是https协议开头,很多浏览器默认关闭DNS预解析。第一句话是强制打开DNS预解析的。



前端面试之4-3 页面性能(协商缓存绕晕了)_第2张图片

document.createElement 一个script标签,也即是用js创建一个标签,把标签加到body上面去,或者加到head上都可以。这就是动态脚本加载的简单方式,就是动态创建节点。

难点是后两个。都是异步加载方式。其实就是加载script标签的时候,加上这两个属性。就能完成异步加载。

两个js都是defer,会按顺序执行。下面看代码:

前端面试之4-3 页面性能(协商缓存绕晕了)_第3张图片
前端面试之4-3 页面性能(协商缓存绕晕了)_第4张图片

其中defer1.js 为console.log('defer1');

其中defer2.js 为console.log('defer2');

先执行write,再执行循环,后执行异步加载的js。

前端面试之4-3 页面性能(协商缓存绕晕了)_第5张图片

async1.js里面:console.log('async1');

async2.js里面:console.log('async2');

前端面试之4-3 页面性能(协商缓存绕晕了)_第6张图片

因为本地文件比较小,加载快。如果1里面代码很多,2加载快,有可能2先执行。


前端面试之4-3 页面性能(协商缓存绕晕了)_第7张图片

缓存:你的资源文件在浏览器存在的备份,或者副本。比如页面中有一个图片,请求回来,把图片缓冲在本地。这个本地是放在你的电脑磁盘上的。浏览器下次请求从浏览器直接读,而不会请求图片地址。

强缓存:问都不问,不直接请求,拿过来就用。

协商缓存:浏览器发现本地有这个副本,又不确定用不用它。要跟服务器问一下,协商一下,是不是过期了。

强缓存:请求一个文件的时候,http头上,携带一个或者两个东西, 一个是Expires,过期时间。是一个key vaule值,表示一个绝对时间。因为客户端时间跟服务器端时间可能不一致,这个时间一般是服务器下发的绝对时间。所以后来加了cache - control 这个是相对时间。不管你的客户端时间跟服务器端时间是不是一致。最后以客户端相对时间为止。3600单位是秒。也就是说3600s之内,不会请求服务器。拿到这个资源3600s内,直接从缓存取。这两个时间如果都下发了,以后者为准。

协商缓存:Last-Modified 上次修改的时间,就是说拿到这个文件的时候,浏览器会在资源文件的http响应头加一个Last-Modified。其实就是后面的时间。然后

前端面试之4-3 页面性能(协商缓存绕晕了)_第8张图片


当强缓存过期失效了,浏览器觉得在这个时间之外了,要请求了,不确定这个东西有没有变化,携带你上次给我的时间 Etage 理解为哈希值。有点绕啊。

下面是百度的资料:


什么是浏览器缓存

浏览器缓存(Brower Caching)是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档。

浏览器缓存的优点有:

减少了冗余的数据传输,节省了网费

减少了服务器的负担,大大提升了网站的性能

加快了客户端加载网页的速度

在前端开发面试中,浏览器缓存是web性能优化面试题中很重要的一个知识点,从而说明浏览器缓存是提升web性能的一大利器,但是浏览器缓存如果使用不当,也会产生很多问题。所以,结合最近遇到的案例,本文对浏览器缓存相关的知识进行总结归纳。

浏览器缓存的分类

浏览器缓存主要有两类:协商缓存和强缓存。

浏览器在第一次请求发生后,再次请求时:

浏览器会先获取该资源缓存的header信息,根据其中的expires和cahe-control判断是否命中强缓存,若命中则直接从缓存中获取资源,包括缓存的header信息,本次请求不会与服务器进行通信;

如果没有命中强缓存,浏览器会发送请求到服务器,该请求会携带第一次请求返回的有关缓存的header字段信息(Last-Modified/IF-Modified-Since、Etag/IF-None-Match),由服务器根据请求中的相关header信息来对比结果是否命中协商缓存,若命中,则服务器返回新的响应header信息更新缓存中的对应header信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容

强缓存

强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。

Expires

该字段是http1.0时的规范,它的值为一个绝对时间的GMT格式的时间字符串,比如Expires:Mon,18 Oct 2066 23:59:59GMT。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。

Cache-Control

Cache-Control是http1.1时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对时间,例如Cache-Control:max-age=3600,代表着资源的有效期是3600秒。Cache-Control与Expires可以在服务端配置同时启用,同时启用的时候Cache-Control优先级高。

协商缓存

协商缓存就是由服务器来确定缓存资源是否可用,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问,这主要涉及到下面两组header字段,这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段。

Last-Modify/If-Modify-Since

浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。

当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。

如果命中缓存,则返回304,并且不会返回资源内容,并且不会返回Last-Modify。

ETag/If-None-Match

与Last-Modify/If-Modify-Since不同的是,Etag/If-None-Match返回的是一个校验码。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据浏览器上送的If-None-Match值来判断是否命中缓存。

与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化。

为什么要有Etag

你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;

某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);

某些服务器不能精确的得到文件的最后修改时间。

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

实际问题分析

如文章开头所属,代码更新到线上后用户浏览器不能自行更新,我们不能要求客户在系统更新后都进行一次缓存清理的操作。·

到底该如何解决呢?

在资源请求的URL中增加一个参数,比如:js/mian.js?ver=0.7.1。这个参数是一个版本号,每一次部署的时候变更一下,当这个参数变化的时候,强缓存都会失效并重新加载。这样一来,静态资源,部署以后就需要重新加载。这样就比较完美的解决了问题。


面试官问你,跟缓存相关的HTTP头有哪些?让你写,你能写几个?就是Expires,cache-control,Last-modified,if-Modified-Since,Etag,If-None-Match

面试官问不问你缓存,首先看你项目有没有体现,涉及,如果项目有相关的内容,就很容易问你,没有的话,就只是有可能问你。

你可能感兴趣的:(前端面试之4-3 页面性能(协商缓存绕晕了))