渲染引擎和 JS 引擎?
网页在客户端的呈现, 重度依赖于浏览器。因此,了解浏览器在网页渲染方面的过程和机理,必利于网页开发。
如何解释两个引擎?
现代浏览器都有两个基本工作, 把页面呈现出来[渲染引擎(HTML、CSS)]和对 JS 的处理[JS 引擎], 两个过程可以通过 DOM 数据结构联系起来。
那什么是浏览器内核?
内核其实就是引擎的别名,起初包含 JS 引擎,(随着 JS 的扩展,不仅仅只有浏览器使用 JS 引擎),现在一般只表示渲染引擎
主流浏览器和引擎
1.看市场, 了解趋势
2020 年浏览器的市场份额占比

2.主流的浏览器都用什么引擎
- firefox:
Gecko
- chrome & opera:
Blink
[Google 联手 Facebook、IBM、Opera 等大厂开发]
- safari:
Webkit
- IE:
Trident
- Edge:
Edgehtml
=>Blink
[2020 年发布]
- firefox:
SpiderMonkey
- chrome:
V8
[目前最通用,用于 Nodejs 和 Deno 项目]
- safari:
javascriptcore
- IE:
chakra
- Edge:
chakra
=>V8
[2020 年更新]

渲染引擎机理(简)
1.渲染引擎的主要工作
为了呈现页面,渲染引擎需要:
- 1.解析成对象模型:
- 找到页面结构(内容):首先, 读取 HTML 文件, 根据其编码把它转换成字符;利用 html 的标签以及标签之间的层级关系创建
DOM tree
- 看看页面长啥样: 同理
DOM tree
, 分析 CSS 生成CSSOM Tree


为什么要解析成对象模型: 比如 DOM 和 CSSOM 两者都是对象模型( OM 后缀), 从上面的图例也可以看出它们都是树形数据结构,而树形结构的最基本单元 ——— node 节点, 其中每个 node 节点都含一个对象(比如 document.documentElement 是根 node,通过这个 node 的信息我们知道它对应的对象是整个 HTML), 对象里的属性和方法就可以描述或和操作这个节点(这就可以很好地解释我们通过 JS 获取的元素集合为什么是 NodeList),所以可以理解为有了对象模型, 页面文档具有编程接口, 就可以利用 js 操作页面中的内容。
- 2.根据 js 更改
DOM Tree
CSSOM Tree
[js 没有更改则跳过]
- 3.合并
DOM Tree
和CSSOM Tree
, 生成Render Tree
: Render Tree
是最终用于布局, 所以一些不参与布局的内容不会被加入到Render Tree
中(比如<meta>
<link>
display:none
等)DOM Tree
和CSSOM Tree
不会被删除 , 方便 js 的交互
- 4.计算布局(computing layout) 根据
Render Tree
来排版布局, 以计算每个节点的几何信息(位置 尺寸)注意:(只要几何布局不改变)第二次渲染并不一定需要此步骤,比如改变了元素颜色,不需要进行二次排版布局
- 5.绘制页面(paint)
布局完成后, 浏览器根据布局确定每个像素点的显示,利用 GPU, 完成网页的绘制;至此, 一个 UI 制作完毕,我们就可以看见页面啦!
我画了一个简单的流程图简要概括以上的五个步骤:

重排和重绘 [reflows/layouting & Repaints]
注:reflows 又可称作 layouting(回流)
简单点说, 初次浏览器渲染后, 由于 CSS、JS 有动画存在,JS 也可以进行许多动态操作, 会导致网页会进行二次渲染,再次执行以上的步骤
注意:渲染的第四步(computing layout)可以在二次渲染的时候跳过,前提是不改变页面的几何布局
因为第四步的可跳过性,我们把二次渲染分为重排和重绘(分别对应第 4、5 步)
前三步也会执行,但是处理速度很快,所以忽略
如何区分两者?
- 重排:对于影响布局的更改,浏览器会进行重排
- 实列:设定宽高、浮动、定位、
input
内容更改、DOM 操作等等
- 重绘:相对直观——只要页面可视内容发生改变,一定会重绘。比如透明度、 颜色等
为什么要关注重排和重绘?
它们成为前端性能优化的切入点,需要减少重回和重排的次数来尽量优化性能,绘制更流畅的 UI,获得更佳的用户体验
浏览器有帮我们优化吗?
- 浏览器也很懒,不会傻到每一次小的变动都去重新渲染,多个连续的页面变化会暂时集中储存到一个队列,每一个 frame 批次执行更改并且清空队列,再去执行渲染步骤。不过有几个列外(当我们需要实时获取页面的状态时,队列会被强制清空用于获取最新最精确的状态):
- 请求 JS 盒子模型的属性,如
clientTop
scroolTop
等等 - 请求获得元素样式、宽高:
ele.width
ele.getComputedStyle()
等等
- 第一步不一定需要全部重新执行(可以只有部分重新更改)
- 第二步本身是不存在于初次渲染中的,但如果页面载入时 JS 便对页面 DOM 或 CSSOM 进行了更改,为避免连续渲染两次,会先执行更改,再执行第三步
- 只要重新渲染,第三步一定重新执行,重新生成
Render Tree
自己如何优化?
网络上有比较好的例子,在这里备注提供几个地址
JS 引擎
参考及补充:
欢迎讨论、指正