浏览器中的进程和线程
- 进程:一般指一个程序。浏览器中,每打开一个页面,或者每一个插件扩展程序,都是一个进程。一个进程包含一到多个线程。
- 线程:进程中具体去执行不同分工的子程序就是线程。一个线程同时只能干一件事情。比如浏览器中发送请求,渲染页面分别是不同的线程。
浏览器进程中的线程
浏览器的一个进程中包含以下线程:
- GUI渲染线程:渲染页面
- JS引擎线程:解析JS代码的
- HTTP网络线程:可以开辟多个,从服务器获取资源和数据的
- 定时器监听与触发线程
- DOM事件监听与触发线程
这几个线程同时工作。注意js引擎是单线程的。
同步编程与异步编程
- 同步编程:一般是只有一个线程去处理事情,上面的事情处理不完,下面的事情无法处理(一件事一件事去干)
- 异步编程:
- 多线程异步编程
- 单线程异步编程 。 JS是用EventQueue+EventLoop机制(事件队列和事件循环机制)完成单线程异步编程的
参考:
浏览器解析、渲染页面的过程
MDN这篇文章详细说明了从输入url到页面渲染完成发生了什么
首先经过导航(输入URL,进行DNS解析,建立连接)、响应(发送请求,接收响应HTML文件)两大过程后,浏览器就会接收到数据的第一块,就开始进行解析过程,最后经历渲染过程。
下面详细说一下解析和渲染过程做了什么。
解析
-
构建DOM树。处理html标签并构建DOM树。根据标签形成的DOM树用来描述节点与节点之间的关系层级等。
- 在这个过程中会遇到img标签,音视频,link标签(css)等非阻塞资源,这时构建DOM树的过程不会停止,会异步加载这些非阻塞资源。
- 遇到script标签(没有 async 或者 defer 属性)默认会阻塞加载,同步进行加载,并执行js。暂停html渲染为DOM树,渲染完成后会触发
DOMContentLoaded
事件。 - 在执行js的时候,如果遇到js死循环,例如
while(1){}
,那么浏览器会一直暂停渲染DOM树,因为浏览器要等js执行完才能继续渲染,但是如果js文件因为网络问题请求不回来了,浏览器就会跳过js的加载,继续渲染DOM,继续接下来的步骤。浏览器会自己判断时网络问题还是js死循环
-
构建CSSOM树。在link标签或者css文件加载完成时,就会开始构建CSSOM树。浏览器遍历CSS中的每个规则集,根据CSS选择器创建具有父、子和兄弟关系的节点树。
-
编译执行JavaScript,穿插在上面两个过程中。当DOM树,CSSOM树正在被解析并创建是时,javascript文件有可能被加载完,加载完就会将javascript编译为可执行的字节码。
渲染
渲染步骤包括样式(Style)、布局(Layout)、绘制(Paint)。
这三个步骤在一些地方也叫做 合成Render树,回流/重排,重绘
-
样式(Style):将DOM和CSSOM组合成一个Render树(渲染树),Render树根据DOM和CSSOM计算并保存出所有结点的内容和样式。浏览器未来根据渲染树来绘制页面。
-
布局(Layout):回流确定整个页面所有元素的大小和位置。
-
绘制(Paint):浏览器将在布局(回流)阶段计算的每个元素转换为屏幕上的实际像素。
在绘制的过程中,有一个分层绘制的过程
每一层都是一个文档流,回流和重绘都在当前的文档流中进行
transform的操作都是在新的文档流上进行操作的,所以性能较好。
完成以上完成以上过程,当页面继续加载资源时,例如加载一个新的图片,或者改变元素位置,删除一个新元素,都会发生回流(重新计算布局,计算元素的位置)和重绘(重新转化为屏幕上的像素)
也就是说,页面第一次渲染,必然会引发一次回流和重绘
如果我们改变了元素的位置和大小,浏览器需要重新计算元素在视口中的位置和大小信息,重新计算的过程是回流/重排,一但发生了回流操作,一定也会触发重绘。所以一旦进行DOM操作,就会产生回流和重绘,很消耗性能,vue和react的的虚拟DOM在内部做了很多DOM操作优化处理,通过算法实现差异化渲染,所以性能很好。
但是如果只是一些普通样式的改变,位置和大小不变,只需要重绘即可
总结
浏览器渲染(解析)页面的过程如下:
- 导航:输入URL、DNS解析、建立连接
- 响应:发送请求、接收第一次响应的HTML文本
- 解析:构建DOM、构建CSSOM、编译javascript
- 渲染:样式(Style,构建Render树)、布局计算(Layout,回流/重排)、绘制(Paint,重绘)。
其中解析和渲染步骤比较重要
关键渲染路径(Critical rendering path) CRP
我们将解析和渲染的步骤中关键的五步提取出来,作为浏览器的关键渲染路径,优化关键渲染路径可提高渲染性能
MDN中的解释:
关键渲染路径(Critical rendering path)是浏览器将 HTML,CSS 和 JavaScript 转换为屏幕上的像素所经历的步骤序列。优化关键渲染路径可提高渲染性能。关键渲染路径包含了 文档对象模型 (DOM),CSS 对象模型 (CSSOM),渲染树和布局。
这五步分别是
- 第一步是处理HTML标记,构建DOM树
- 第二步是处理CSS,构建CSSOM树。
- 第三步是将DOM和CSSOM组合成一个Render树。
- 第四步是在依据渲染树计算每个节点的大小和位置。
- 最后一步是根据渲染树和回流得到的几何信息,得到节点的绝对像素,将各个节点绘制到屏幕上。
即:构建DOM->( 执行js?这一步不一定,因为就是可能没加载完js)->构建CSSOM->构建Render树->回流->重绘。
参考: