序言
想要更好的理解浏览器是如何解析HTML语言,我们就得去了解浏览器的基本工作原理,因此本文以Chrome浏览器为例,介绍了浏览器基本工作原理和HTML在浏览器中是如何解析成我们所看见的网页。
浏览器如何工作
浏览器是运行在操作系统上的应用程序,它有两种架构,一种是单进程架构,这是早期的浏览器,它的工作方式就是只启动一个进程,在这个进程里面有多个线程协同工作。第二种是多进程架构,它的工作方式就是会启动多个进程,每个进程里面有多个线程。因为每个进程间分配空间是独立的,如果进程之间需要传递数据,则需要通过IPC(Inter Process Communication)进行通信。这样的好处是当一个进程死掉后,不会影响其他进程。
Chrome浏览器简介
Google Chrome是一款由Google公司开发的网页浏览器, 它基于开源引擎WebKit、Blink,在脚本理解方面,Chrome使用自己研发的V8引擎。当前的Chrome浏览器是一个多进程架构,它为每个页面或iframe都分配多个进程,具体工作如下图:
各个进程的工作:
进程 | 负责工作 |
---|---|
浏览器进程 Browser Process | 负责浏览器的“Chrome”部分, 包括导航栏,书签, 前进和后退按钮。同时这个进程还会控制那些我们看不见的部分,包括网络请求的发送以及文件的读写。 |
渲染器进程 Renderer Process | 控制选项卡内,网站里显示的所有内容。 |
插件进程 Plugin Proces | 控制网站使用的插件,例如:Flash。 |
GPU进程 GPU Process | 独立于其他进程,用于处理 GPU 任务。被单独拆分出一个进程,因为 GPU 处理来自多个应用程序的请求并将它们绘制在同一个表面上。 |
浏览器解析HTML过程
一、请求文档:
- 在浏览器中输入URL进行搜索
- 如果输入内容是网址,则通过DNS(Domain Name System)域名解析协议来将域名和IP地址相互映射,找到目标,否则会启动搜索引擎进行查询。
- 与目标地址建立TCP/IP连接(进行三次握手,四次挥手),收到目标文档。
- 通过Safe Browsing(谷歌内部的一套安全站点系统)检测目标站点是否安全,安全则通知渲染进程开始工作。
二、解析文档构建DOM树:
- DOM (Document Object Model,文档对象模型,构建DOM是必不可少的一环,浏览器从发出请求开始到得到HTML文件后,第一件事就是将HTML通过Tokeniser标记化,通过词法分析解析,根据识别后的标记进行DOM树的构造。
-
解析 HTML 构建 DOM 时,遇到 Javascript 会被阻塞,因此Javascript我们常常把它放到文档最后或者异步执行JS。
三、生成Layout树:
- 知道了节点和每个节点的样式后就需要知道每个节点该在什么位置和占用多大的区域,通过遍历DOM和CSS样式生成Layout Tree,它的每个节点有它的方位、颜色和大小等元素。
- Layout Tree与DOM Tree节点并不是一一对应的,display:none不会出现在Layout Tree上,伪类元素content有值的元素会出现在Layout Tree上。因此,Layout Tree有多少节点,我们就能看见多少。
四、生成Layer树:
- 当我们知道节点的位置和样式后,我们还得知道需要以什么样的顺序进行渲染,此时就会生成一个绘制记录表(Paint Record),该表记录了绘制顺序。
- 再遍历Layout Tree生成一个有绘制顺序的Layer Tree。
五、绘制画面:
- 绘制顺序确定后,主线程将绘制信息传递给合成器线程。
- 合成器线程将每个图层分块发送给栅格化线程进行栅格化,并且生成合成器帧。
- 然后通过IPC将合成器帧传送给浏览器进程。
- 浏览器进程再传给GPU才能渲染到页面上。
小结
当一个元素顺序改变后会产生重排,样式改变后会产生重绘,它们和Javascript一样都会占用主线程。如果运行大量动画,就会不断消耗主线程,从而导致页面卡顿。怎样优化呢?Javascript可以采用request AnimationFrame()方法进行优化,该方法可以将JS代码分块到每一帧的间隙去调用,就可以在视觉上感受不到卡断。CSS动画优化可以采用Transform属性,它不会进入主线程,而是直接运行在合成器线程和栅格化线程中。