tech··17 分钟阅读

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

浏览器的缓存,浏览器渲染原理,存储,跨域

#笔记

浏览器的缓存

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

  • 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 的不稳定。

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

浏览器渲染原理

浏览器的渲染主要是 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 去替换

考点 3:优化,减少阻塞

  1. 减少选择器的使用,这样能减少 DOM 遍历的层级,降低渲染的文件的大小
  2. script 标签会阻塞渲染进程,所以我们的 script 代码应该写在 html 文件的下面。
  3. 没有任何依赖的 js 文件我们可以加上 asyac 属性,这样就不会影响渲染的进度。

考点 4:重绘和回流

  • 重绘不改变布局,只改变一些颜色什么的
  • 回流会改变布局。
  • 回流一定会引发重绘。

浏览器的存储

Cookie, LocalStorage, sessionStorage, IndexedDB

Cookie

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

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

缺点:

  • 内存较小一般就几 k 大小,所以只能保存用户信息不能保存大文件内容。
  • cookie 过多可能会带来过的性能消耗。
  • cookie 还存在一定的安全性。

LocalStorage

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

sessionStorage

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

IndexedDB

  • 内存无线
  • 永久保存

跨域

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

解决跨域的四个方法:

  1. From 表单能够帮我们跨域请求信息。疯狂发送请求
  2. jsonp 利用的没有跨域限制请求
  3. cors 后端设置允许跨域,或者搞个白名单,允许那些能跨域请求
  4. nginx 代理

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

评论区