当我们打开一个网页,浏览器做了什么?
当我们打开一个网页,浏览器是如何将一堆代码渲染成我们看到的页面的呢?这篇小博客简单的介绍了一下浏览器在网页渲染过程中做的一些事情,关于这方面的内容,《webkit技术内幕》中有比较全面的讲解,内容比较偏浏览器底层实现,涉及了一些webkit的C++代码,讲的还是比较清楚的。
参考资料:
1. 《How browsers work》英文版 \ 中文翻译版
2. 浏览器前端优化
总览
当我们用浏览器打开一个网页这背后,浏览器做了哪些工作呢?
先来个列表总结一下,后面慢慢展开。
1. 使用HTML创建文档对象模型(DOM)
2. 使用CSS创建CSS对象模型(CSSOM)
3. 基于DOM & CSSOM执行脚本(Scripts)
4. 合并DOM & CSSOM形成渲染树(RenderTree)
5. 使用渲染树布局所有元素(Layout)
6. 渲染所有元素(Paint)
还是直接看图直观
1. 创建DOM
DOM可以以一种独立于平台和语言的方式访问和修改一个文档的内容和结构,定义了一组接口,利用接口可以对DOM树进行操作。
在这一阶段,HTML解释器将网络或者磁盘读取的HTML网页和资源从字节流解码成字符流,通过词法分析器解释成词语,再通过语法分析器构建成节点,最后这些节点被构建成DOM树。
(浏览器中HTML解释器可以利用单独的线程来解释HTML文档的。当字节流通过IO线程传递给渲染线程后,渲染线程负责解释、布局和渲染等工作。DOM树也是在渲染线程上创建和访问的,即DOM树的构建过程只能在渲染线程。但是从字符串到词语这个阶段可以交给单独的线程来处理。)
2. 构建CSSOM
CSSOM提供了一些方法可以让开发者自定义一些脚本去操作CSS状态,基本思想是在DOM中的一些节点接口中,加入获取和操作CSS属性的JS接口。即DOM提供接口让JS修改HTML文档,CSSOM提供接口让JS获得和修改CSS代码设置的样式信息。
CSS解释过程是指CSS字符串经过CSS解释器处理后变成渲染引擎的内部规则的过程。CSS解释器工作在DOM树建立之后,RenderObject树建立之前。CSS解释器解释后的结果会保存起来,然后RenderObject树基于这个结果来进行规范匹配和布局计算。
3. 执行script
在第一步的HTML解释器的工作过程中,会有JS的代码需要执行,它发生在将字符串解释成词语后、创建节点时。这也是为什么有时候JS代码不能访问DOM的原因,因为这时候DOM树还没有创建。
4. 构建Render树
在DOM和CSSOM构建完成后,就需要为DOM构建RenderObject树。
RenderObject树是基于DOM构建的树,是为了布局计算和渲染等机制而构建的一种内部表示。一个RenderObject对象保存了为了绘制DOM节点所需要的各种信息如样式布局信息。
RenderLayer树是基于RenderObject树建立的树,每个RenderLayer对象可以想象成图像的一个层,各层一起构成一个图像。
5. 布局
创建RenderObject之后,每个对象是不知道自己的大小位置信息的,浏览器引擎根据盒模型来计算他们的大小位置信息,这个过程称为布局计算,它的基础是盒模型,从外到内依次是margin、border、padding、content。布局计算是一个递归的过程,因为需要先计算子节点的位置和大小等信息。
哪些情况下需要重新计算布局?
只要样式发生变化,都需要重新计算布局
1. 网页首次被打开的时候
2. 网页的动画会触发布局计算
3. JS修改样式信息的时候
4. 用户的交互也会触发,比如翻滚网页触发新区域的布局计算
6. 渲染
在RenderObject树和RenderLayer树创建后,浏览器将内部的这些对象模型转换成可视化的结果,经历两个阶段:
1. 将每层的内容进行绘制
2. 绘制完毕后将这些绘图的结果合成为一个图像
软件绘图: 绘图操作使用CPU完成(没有合成阶段)
GPU硬件加速绘图: 绘图操作由GPU完成