开篇
作为一个前端开发者,与我们打交道最多的就是浏览器,那么问题就来了,如今市面上浏览器那么多,但是那一个是最适合最好用的前端开发工具呢?也许不用说,大家都会异口同声的说出是Chrome吧,为什么呢,就我个人看来,它总是积极拥抱新的技术,而且还有很好用的开发调试工具等等吧。所以今天我们就来说一说浏览器的问题,浏览器一般都由用户界面,浏览器引擎,渲染引擎(排版引擎),JavaScript引擎,UI后端,网络模块和数据的持久化存储这几个模块组成。今天,我们主要说的就是浏览器的渲染引擎。由于JavaScript引擎越来越独立,所以一般现在说的浏览器内核主要指的就是渲染引擎(Webkit,Gecko)
渲染引擎的作用
渲染引擎解析html文档,css文档,将解析后的css规则应用到html标签元素上,最后将html渲染到浏览器窗口中以显示具体的DOM内容
渲染引擎的工作流程
1.解析HTML构建DOM树 -> 2.构建渲染树 -> 3.渲染树布局阶段 -> 4.绘制渲染树
复制代码
- 解析HTML构建DOM树:渲染引擎将HTML标签解析成由多个DOM元素对象节点组成的具有父子关系的DOM树结构
- 构建渲染树:根据DOM树结构的每个节点顺序提前计算使用的css规则并重新计算DOM树结构的样式数据,生成一个带样式描述的DOM渲染树对象
- 渲染树布局:根据渲染树节点在页面中的大小和位置,将渲染树节点固定到页面的位置上,在这个阶段只要是元素的布局属性(position,float,margin等属性)生效
- 绘制渲染树:将渲染树节点的背景、颜色、文本等样式信息应用到节点上,这个阶段主要输样式的内部显示样式(color、background等属性)生效
!:渲染引擎对DOM渲染树的解析和输出是逐行进行的。所以渲染树前面的内容可以先渲染展示,这样就保证了较好的用户体验。其次也不要在HTML中插入script脚本等标签,由于script标签内容的解释执行常常会阻塞页面结构的渲染
在这里我们需要注意的是在渲染树布局和绘制阶段:
- 页面重排(reflow):页面在生成后如果页面元素位置发生改变,一旦页面reflow则必定会repaint
- 页面重绘(repaint):显示样式发生改变但是布局即元素位置不发生改变
reflow产生的代价要远大于repaint,所以我们要尽量避免reflow,减少repaint
渲染引擎渲染DOM的主要流程
在这里我们以webkit和gecko为例,这两种渲染引擎工作流程的区别主要在于解析HTML或者css文档渲染的过程 webkit中HTML和CSS解析我们可以认为是并行的,而gecko则是先解析HTML,生成内容Sink后再开始解析CSS。当然它们在工作过程中所使用的描述术语也是不一样的:
- webkit渲染对象被称为 Render Tree (渲染树)
- gecko 渲染对象呗成为 Frame Tree(Frame树)
Webkit内核渲染DOM流程
Gecko内核渲染DOM流程
HTML解析和CSS解析阶段
一般的渲染引擎都包好了HTML解析和CSS解析阶段,这也就是渲染引擎解析流程中最重要的两个阶段。
- HTML文档解析
-
渲染引擎:逐行解析HTMl文本字符串生成具有父子关系的DOM对象节点的过程
html在解析完成后会生成由多个DOM元素对象组成的DOM树,解析时会对HTML文本标签进行分析,每个标签都会有DOM类型:
-
例如:
<html> (HTMLHtmlElement)
<head> (HTMLHeadElement)
<body> (HTMLBodyElement)
....
复制代码
在这里需要注意的是DOM元素标签和DOM元素对象虽然都是用来描述DOM结构的,但DOM元素标签是指文本化的HTML标识,而DOM元素对象则是指经过渲染引擎DOM解析后生产的具有节点父子关系的树形对象。
- CSS 文档解析
- css解析和html解析方式大体上是一样的,首先也要通过词法解析生成css分析树,使用特定的css文班语法来实现,不同的是,html是使用类似xml结构的语法解析方式来完成分析的。
在渲染树逐渐生成的的阶段,DOM树中的节点会在css分析树中根据元素、类、id选择器来提取与之对应元素的一条或者多条CSSRule,进行CSS规则的层叠和权重计算,得到最终生效的样式CSSRule并添加到DOM树上,形成渲染树。每当DOM节点提取CSS样式完成时,DOM渲染树就形成了。
在已经形成的DOM渲染树中,节点的CSS规则可以通过 document.defaultView.getComputedStyle(element,null) 方法查看
如果一个节点有多条不同的样式规则,则它是通过计算权重的方式来得到结果的
权重规则: !important > 内联样式规则(1000) > id(100) > 类选择器(10) > 元素选择器(1)
结语
了解这些浏览器渲染知识有助于我们解决与优化前端开发过程中的各种问题,本文旨在了解基本的渲染流程和一些基本的概念,当然,这只是我个人在学习过程中了解到的,也是一篇我自己学习当中的总结与记录,也许还有我不了解的,如果有错误或者不清楚含糊的地方,希望大家可以指出来,我必定积极改正。谢谢大家!