浏览器组成:
主流浏览器渲染引擎:
IE:Trident
Chrome28+: Blink
Firefox: Gecko
Opera: Blink
Safari: Webkit
UC: U3
腾讯旗下浏览器: X5/+-Blink
chrome使用多个渲染引擎实例,每个tab页都是一个独立的进程
浏览器线程:
GUI渲染线程:用于渲染页面中的HTML元素;当页面需要回流或重绘时,该进程会执行;当JavaScript引擎运行脚本时,该线程处于挂起状态。
JavaScript引擎:处理页面交互,操作DOM树,CSS样式树,为单线程。
定时触发器线程:定时器并不是由JS引擎来计数的,因为JS是单线程,处于阻塞线程状态时会影响计时的准确,所以通过单独的线程来计时并触发定时。
事件触发线程:当一个事件被触发时,事件触发线程会把事件添加到待处理队列的队尾,等待JS引擎处理。如:定时任务、AJAX请求、鼠标事件等。
异步HTTP请求线程:XMLHttpRequest在连接后是通过浏览器新开一个线程进行请求,检测到状态变更时,如果设置了回调函数,异步线程就会产生状态变更事件放到JS引擎的处理队列中等待处理。
页面加载过程:
- 输入域名
- 浏览器根据DNS服务器得到域名所对应的IP地址
- 向这台IP的服务器发送HTTP请求
- 目标服务器收到请求进行处理并返回HTTP请求
- 浏览器接收到目标服务器返回的内容(HTML格式的字符串)开始渲染出页面
浏览器渲染过程:
- 解析HTML,生成DOM树,解析CSS,生成CSS树
- 将DOM树和CSS树结合,生成渲染树(Render Tree)
- Layout(回流):根据生成的渲染树进行回流,得到节点的几何信息(位置、大小)
- Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
- Display(展示):将像素发送给GPU,最后通过调用操作系统Native GUI的API绘制,展示在页面上
构建DOM的流程:
-
HTML文件被解析生成DOM树:
-
构建CSSDOM:
合并DOM和CSSDOM:只包含可见的节点,遇到<script>就停止渲染,执行JS。
(为了防止渲染出现不可预期的结果,GUI线程和JS引擎线程是互斥的关系,如果JS执行时有CSS修改功能,HTML会先下载解析CSSDOM,再执行JS,修改CSSDOM,最后再渲染DOM)布局与绘制:渲染树生成以后,根据渲染树来布局(Layout/回流),布局流程的输出是一个“盒模型”,精确捕获每个元素的确切位置和尺寸,所有的测量值最后转换为绝对像素。
重绘:重绘节点就是通过构造的渲染树和回流阶段,将渲染树上的每个节点转为屏幕上的像素
发生回流的情况:
- 页面最初渲染的时候
- 浏览器窗口的尺寸发生变化
- 添加可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化
- 内容发生变化
- 元素字体大小变化
- 激活css伪类
回流一定会重绘,重绘不一定回流
重绘不回流的情况:元素样式的改变
回流比重绘的代价要高,有时只回流一个单一元素,但是它的父元素及任何跟随它的元素也会产生回流