浏览器端面试四大问:浏览器的缓存,浏览器渲染原理,存储,跨域(个人笔记)

273 阅读7分钟

浏览器的缓存


www.cnblogs.com/lyzg/p/5125…

浏览器的缓存,缓存的一般是一些内存比较小的静态的资源。缓存的主要位置是:

Service Work 

Memory Cache:浏览器自带,内存较小,速度较快

Disk Cache:存在本地,内存较大,加载速度较慢

Push Cache

缓存策略:

主要分为两种强缓存和协商缓存

强缓存

强缓存是利用Expires 或 cache control 这两个http response header 实现;

强缓存是浏览器现在缓存中查找是否有该资源。命中时状态码为200

Expires:是老浏览器使用的,是一串带有固定时间的字符。他表示的是这个资源缓存的过期时间。

它的工作原理是:

在浏览器第一次向服务器请求资源时,服务器会给浏览器返回资源和带有response的Expires的header。服务器会把资源存在缓存中,当浏览器第二次请求时,它会在缓存中查找是否有这个资源,如果有的话,就把exprice和当前的时间作比较,如果时间过了则未命中去服务器请求资源。命中则从缓存中获取资源。

它的缺点:因为它是和本地时间作比较的,当你的本地时间不准时它很有可能有误差。所以为了解决这个问题就有了cache control;

cache control: 是一串数字,以秒为单位,代表的是过多久时间过期。

它的工作原理是:

在浏览器第一次向服务器请求资源时,服务器会给浏览器返回资源和带有response的cache control的header。服务器会把资源存在缓存中,当浏览器第二次请求时,它会在缓存中查找是否有这个资源,如果有的话,他会根据第一次请求的时间和cache control的时间计算一个资源过期时间,然后拿过期时间和当前请求的时间做对比,如果时间过了则未命中去服务器请求资源。命中则从缓存中获取资源。

它的性能比Expires更好一点,两个可以同时启动也可以只启用一个,如果都启用的话优先cache control。

协商缓存

协商缓存主要是利用http respense header中的ETge和Lastmodified这两组。

协商缓存是在强缓存未命中的情况下,服务器向浏览器发送请求验证协商缓存是否命中。命中时状态码为304。

Lastmodified:

是一串时间字符:代表的是缓存过期的时间

浏览器在第一次向服务器端请求资源时候,服务器端会向浏览器端返回资源和response的header上lastmodified,这个lastmodified表示这个资源在服务器上的最后修改时间。再次向服务端请求资源时,服务端就会返回加上If-Modified-Since的header,他表示的就是上一次请求时返回的Last-Modified的值。根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,来判断是否命中。命中就返回304状态码,同时让浏览器去缓存中拿资源。未命中则就从服务端获取资源。

缺点:当你在浏览器端打开缓存文件时,就是你没有修改文件,浏览器也会判定你修改了资源,这样就会导致协商缓存的判断有误。为了解决这个问题,于是又有了ETag来判断协商缓存。

ETag;

是一段特殊的字符,唯一标识的字符串。

浏览器在第一次向服务器端请求资源时候,服务器端会向浏览器端返回资源和response的header上ETag,一段唯一辨识的字符串,再次请求时也会返回一段ETag,如果资源修改则返回的ETag是不一样的,所以通过判断两者是否相同,来判断资源是否修改,来判断是否命中缓存。

一般浏览器两种协商缓存的方式都会存在,防止Lastmodified的不稳定。

一般协商缓存都是配合着强缓存,如果没有强缓存,协商缓存就没有什么意义。协商缓存主要是为了帮助强缓存判断资源是否更新。

浏览器渲染原理

www.cnblogs.com/gwf93/p/107…

浏览器的渲染主要是5个阶段;

1. 浏览器读取html文件生成DOM树,他先将代码生成指令,这个过程叫做指令化,然后再指令化后,将这些指令生成node节点,这些node节点之间的关系就作为脐带,将这些节点串成一棵DOM树。

2.浏览器读取css文件,将css代码生成cssom。

3.合并DOM树和cssom,生成渲染树。这个过程浏览器递归每个node节点,并给节点一个样式规则并使用。这一步需要注意,display:none并不会出现再渲染树中,它会出现在第一步的DOM树中,里面还会出现注释和script标签。

4.渲染树布局 它会帮我们输出布置每个节点的出现的位置和大小等,就再浏览器端的位置,布置成一个一个的盒模型

5. 渲染树绘制 它会将那些盒模型绘制上它的样式,色彩图片等等

考点1: 为什么操作 DOM 慢?

1. 因为操作DOM用到了两条线程,js的引擎线程和渲染线程,js是单线程执行的,所以两天线程需要通信才能一起执行,这样会大大增加性能消耗。

2. 操作DOM会引起回流和重绘。

考点2:同时加入10万条dom,如何实现不卡顿。

1.分页处理。

2.使用requestAnimationFrame来处理,每过16.6秒循环插入dom.

3.使用虚拟DOM,只加载可视区域的dom,加载更多的时候,用虚拟DOM去替换,bvaughn.github.io/react-virtu…

考点3:优化,减少阻塞

1. 减少选择器的使用,这样能减少DOM遍历的层级,降低渲染的文件的大小

2.script标签会阻塞渲染进程,所以我们的script代码应该写在html文件的下面。

3.没有任何依赖的js文件我们可以加上asyac属性,这样就不会影响渲染的进度。

考点4:重绘和回流

重绘不改变布局,只改变一些颜色什么的

回流会改变布局。

回流一定会引发重绘。

浏览器的存储

juejin.cn/post/684490…

Cookie,LocalStorage,sessionStorage,IndexedDB

Cookie

浏览器是无状态的,他无法记住浏览器上一步做的是什么,所以很多功能无法实现,比如购物车,所以浏览器创建cookie来使用,用于保存用户的状态,在购物东西时cookie就好像一辆购物车,用来保存用户选购的商品信息,它在浏览器和服务器之间来回传输信息。

Cookie指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密)。 cookie是服务端生成,客户端进行维护和存储。通过保存用户的信息,来保存登录状态,登录还刷新还能回到原来的状态。可以保存一段时间。

缺点:内存较小一般就几k大小,所以只能保存用户信息不能保存大文件内容。

cookie过多可能会带来过的性能消耗。

cookie还存在一定的安全性。


LocalStorage

内存较大有5M左右,除非被清除否则永久保存,接口容易封装,仅在浏览器中保存,不参与通信

sessionStorage

内存较大有5M左右,关闭页面就消失,接口容易封装,仅在浏览器中保存,不参与通信

IndexedDB

内存无线,永久保存。




跨域

数据的请求都要遵循同源策略,既需要同域名,同端口,同协议。所以违反了这个规则则就算跨域了。

解决跨域的四个方法:

From表单能够帮我们跨域请求信息。疯狂发送请求

jsonp  利用<script></script>的没有跨域限制请求

cors 后端设置允许跨域,或者搞个白名单,允许那些能跨域请求

nginx 代理

最后:

有时间再整理跨域和存储。