文章目录
1. 浏览器工作原理
1. 浏览器
- 浏览器内核:支持浏览器运行的最核心的程序
- 浏览器内核分类:
- Chrome,Safari /səˈfɑːri/:webkit
- firefox:Gecko /ˈɡekəʊ/
- IE:Trident /ˈtraɪdnt/
浏览器都是多线程运行的
2. 浏览器多进程架构
-
浏览器主进程。 主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
-
渲染进程。 核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
-
GPU 进程。 其实,Chrome 刚开始发布的时候是没有 GPU 进程的。而 GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。
-
网络进程。 面向渲染进程和浏览器进程等提供网络下载功能。,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。
-
插件进程。 主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。
- 仅仅打开了 1 个页面,为什么有多个进程?
因为打开 1 个页面至少需要 1 个网络进程、1 个浏览器进程、1 个 GPU 进程以及 1 个渲染进程,共 4 个;如果打开的页面有运行插件的话,还需要再加上 1 个插件进程。
- 仅仅打开了 1 个页面,为什么有多个进程?
3. 从输入 URL 到页面展示,这中间发生了什么?/ 浏览器运行机制 [经典面试题]
从输入 URL 到页面展示整个过程,称为浏览器运行机制。
-
用户输入
当用户在地址栏中输入内容后,地址栏会判断输入的内容是搜索内容,还是请求的 URL。
如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索关键字的 URL。
如果判断输入内容符合 URL 规则,那么地址栏会根据规则,把这段内容加上协议,合成为完整的 URL。 -
URL 请求过程
- 浏览器进程会通过进程间通信(IPC)把 URL 请求发送至网络进程,网络进程接收到 URL 请求后,会在这里发起真正的 URL 请求流程。
- 首先,网络进程会查找本地缓存是否强缓存了该资源。如果有缓存资源且资源未失效,那么直接返回资源给浏览器进程;如果在缓存中没有查找到资源,那么进入网络请求流程。首先进行DNS 解析,以获取请求域名的服务器 IP 地址,利用 IP地址和服务器通过三次握手建立TCP 连接。如果请求协议是 HTTPS,那么还需要建立 SSL/TLS 连接。连接建立之后,浏览器会向服务器发送请求。
- 服务器接收到请求信息后,会根据请求信息生成响应数据,并发给网络进程。等网络进程接收了响应数据之后,就开始解析响应头的内容。
- 网络进程解析响应头,如果发现返回的状态码是 301 或者 302,那么说明服务器需要浏览器重定向到其他 URL。这时网络进程会从响应头的Location 字段里面读取重定向的地址,然后再发起新的 HTTP 或者 HTTPS 请求。如果是304,则表示使用协商缓存(一般是js\css\图片等资源),从本地缓存获取数据,流程结束。如果响应行是200,那么表示浏览器可以继续处理该请求。
- 响应数据类型处理。浏览器会根据 Content-Type 的值来决定如何显示响应体的内容。如果是js/css/图片等静态资源,Content-Type 字段的值被浏览器判断为下载类型,那么该请求会被提交给浏览器的下载管理器,流程就此结束。但如果是HTML,那么浏览器则会进行页面渲染,所以接下来就需要准备渲染进程了。
-
准备渲染进程
默认情况下,Chrome 会为每个页面分配一个渲染进程,也就是说,每打开一个新页面就会对应创建一个新的渲染进程。但是,如果从 A 页面打开 B 页面,且 A 和 B 都属于同一站点的话,那么 B 页面复用 A 页面的渲染进程【同一站点:拥有相同的协议和根域名】。下一步进入提交文档阶段。 -
提交文档
这里的“文档”是指 URL 请求的响应体数据。
“提交文档”的消息是由浏览器进程发出的,渲染进程接收到“提交文档”的消息后,会和网络进程建立传输数据的“管道”。等文档数据传输完成之后,渲染进程会返回“确认提交”的消息给浏览器进程。浏览器进程在收到“确认提交”的消息后,会更新浏览器界面状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新 Web 页面。
-
渲染阶段
浏览器的渲染过程,解析DOM生成DOM Tree,解析CSS生成CSSOM Tree,两者结合生成渲染树,根据渲染树来进行重排重绘的过程,渲染成最终页面。- 构建DOM树
这是因为浏览器无法直接理解和使用 HTML,所以需要将 HTML 转换为浏览器能够理解的结构——DOM 树。JavaScript会阻塞 DOM 生成,而样式文件又会阻塞 JavaScript 的执行
例: - 构建cssom树
(1). 把 CSS 转换为浏览器能够理解的结构。当渲染引擎接收到 CSS 文本时,会执行一个转换操作,将 CSS 文本转换为浏览器可以理解的结构——styleSheets结构。
(2). 转换样式表中的属性值,使其标准化。 css文本中有很多属性值,如 2em、blue、bold这些类型数值不容易被渲染引擎理解,所以需要将所有值转换为渲染引擎容易理解的、标准化的计算值,这个过程就是属性值标准化。
例:
(3). 依据CSS 的继承和层叠规则,计算出 DOM 树中每个节点的具体样式,生成CSSOM 树。
- CSS 的继承规则
CSS 继承就是每个 DOM 节点都包含有父节点的样式。 - CSS 的层叠规则:
2.1. 由于继承而发生样式冲突时,最近祖先获胜。
2.2. 继承的样式和直接指定的样式冲突时,直接指定的样式获胜。
2.3. 直接指定的样式发生冲突时,样式权值高者获胜。
2.4. 样式权值相同时,后者获胜。
2.5. !important的样式属性不被覆盖。
3. 将dom树和cssom树组合成渲染树
在解析完html和css文件,生成 DOM 树和 CSSOM 树以后,就需要将这两棵树组合为渲染树。
当浏览器生成渲染树以后,就会根据渲染树来进行重排重绘的过程,调用 GPU 绘制,合成图层,显示在屏幕上。对于这一部分的内容因为过于底层,还涉及到了硬件相关的知识,这里就不再继续展开内容了。 - 构建DOM树
-
最后一步是TCP通过四次挥手断开连接。
重绘&重排
重绘&重排都发生在渲染树构建完成以后,页面在首次进行绘制时,必然经历重排重绘。
1. 重绘
- 重绘是DOM节点中的各个元素都是以盒模型的形式存在,当一个盒模型外观的改变时,所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
- 触发重绘的条件:改变元素外观属性。如:color,background-color等。
- 注意:table及其内部元素可能需要多次计算才能确定好其在渲染树中节点的属性值,比同等元素要多花两倍时间,这就是我们尽量避免使用table布局页面的原因之一。
2. 重排(重构/回流/reflow)
-
重排 :当渲染树中的一部分或全部因为元素的规模尺寸,布局,是否隐藏等的改变而需要重新构建, 这就称为重排。每个页面至少需要一次重排,就是在页面第一次加载的时候。
-
重绘和重排的关系:在重排的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成重排后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。所以,重排必定会引发重绘,但重绘不一定会引发重排。
-
触发重排的条件:任何页面布局和几何属性的改变都会触发重排,比如:
- 页面渲染初始化;(无法避免)
- 添加或删除可见的DOM元素;
- 元素位置的改变,或者使用动画;
- 元素尺寸的改变——大小,外边距,边框;
等等
重绘重排的代价:耗时,导致浏览器卡慢。
* 为什么有时候用translate而不是用绝对定位来改变位置
translate 是 transform 属性的⼀个值。改变transform或opacity不会触发浏览器重排(reflow)或重绘(repaint)。⽽改变绝对定位会触发重排,进⽽触发重绘。transform使浏览器为元素创建⼀个 GPU 图层,但改变绝对定位会使⽤到 CPU。 因此translate()更⾼效,可以缩短平滑动画的绘制时间。 ⽽translate改变位置时,元素依然会占据其原始空间,绝对定位就不会发⽣这种情况。