《十八》浏览器的渲染引擎

本文深入解析浏览器如何渲染网页,包括从输入URL到页面呈现的全过程,介绍浏览器内核、渲染引擎及JS引擎的工作机制,探讨缓存、回流与重绘等优化技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

渲染引擎用来解析 HTML 和 CSS,渲染网页。

渲染引擎用来渲染页面,JS 引擎用来解析和执行 JS。
由于 JS 是单线程的,因此浏览器的 JS 引擎和渲染引擎是互斥的,当其中一个执行时,另一个只能挂起等待。
请添加图片描述

常见的浏览器内核:

浏览器内核本来是分成渲染引擎和 JS 引擎两部分,但是由于 JS 引擎越来越独立,浏览器内核就倾向于只指渲染引擎了。正是因为浏览器内核不同,浏览器才有兼容问题。

  1. Chrome 浏览器以前是 Webkit 内核,现在是 Blink 内核。
  2. Edge 浏览器以前是 Webkit 内核,现在是 Blink 内核。

    Edge 浏览器是微软研发的,在 Windows10 中取代 IE 浏览器成为默认浏览器。
    IE 浏览器是 Trident 内核,在 2023 年 2 月 14 日永久停用。

  3. Opera 浏览器最初是自己的 Presto 内核,后来是 Webkit,现在是 Blink 内核。
  4. Safari 浏览器是 Webkit 内核。
  5. Firefox 浏览器是 Gecko 内核。

UC 浏览器、百度浏览器是 Trident 内核。
360 浏览器、搜狗浏览器是 Trident + Webkit 双内核。

和钱相关的会自动选择 Trident 内核,安全性高一些;其余时候会只能选择 Webkit 运行。

浏览器的渲染引擎解析一个网页的过程:

请添加图片描述

  1. HTML --> HTML Parser --> DOM Tree:渲染引擎对 HTML 从上到下进行解析,生成 DOM 树。
    请添加图片描述

  2. Style Sheets --> CSS Parser --> Style Rules:在解析 HTML 的过程中,如果发现有 CSS,对其进行解析,生成 CSSOM 规则树。

    CSS 的下载和解析不会阻塞 HTML 的继续解析。

    请添加图片描述

  3. Attachment:将解析完成的 CSSOM 规则树应用到 DOM 树上生成渲染树。在渲染树上有记录每个节点的样式信息,但是没有记录大小信息和位置信息。

    只有 DOM 树和 CSS 规则树都解析完成,才能生成渲染树。
    也就是说, CSS 文件的下载和解析不会影响 DOM 树的生成,但是会影响渲染树的生成。

    DOM 树和渲染树可能不是一一对应的。比如:某个元素的 CSS 属性是 display:none,默认不需要渲染出来。这个元素在 DOM 树上是存在的,在渲染树上是不存在的。

    为了达到更好的用户体验,浏览器的渲染引擎会尽快将已经构建好的一部分内容显示在屏幕上,而不必等到整个 HTML 文档都解析完毕之后才开始构建渲染树树和布局进行绘制。

请添加图片描述

  1. Layout:计算布局样式,得出渲染树上的每个节点的大小信息和位置信息,生成绝对的坐标。
  2. Painting:将渲染树中的每个节点转为实际的像素点绘制到屏幕上,显示出来。

浏览器的回流与重绘:

请添加图片描述

回流一定会引起重绘,非常消耗性能;重绘不一定会引起回流,性能消耗相比回流来说要小。

回流 reflow(重布局、重排):

第一次计算节点的大小和位置,称为布局;之后修改了节点的大小和位置重新计算,称为回流。

由于浏览器的流布局,对渲染树的计算通常只需要遍历一次就可以完成。但 table 及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性,这就是应该尽量避免使用 table 布局页面的原因之一。

引发回流的操作:

  1. DOM 树结构发生变化:添加节点、删除节点。
  2. 改变了布局:修改元素的尺寸、位置信息。
  3. 浏览器窗口 resize。
  4. 获取元素的一些属性时:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() 等。

    当获取这些全局属性时,此时页面上的其他元素的布局和样式需要处于最新状态,这会引起多次的回流和重绘,称为强制回流。

回流优化的方法:

  1. 尽量避免频繁地 DOM 操作:可以在一个 DocumentFragment 或者父元素中将要执行的 DOM 操作都执行完,再一次性地添加到 DOM 上。
  2. 修改元素的大小、位置时尽量一次性修改。

    例如:要将 box 的宽改为 100px,高改为 200px,最好不要使用 box.style.width = '100px'; box.style.height = '200px'; 这种方式一个一个修改,可以通过动态添加 class 的方式一次性修改。

  3. 脱离文档流的元素的变化不会影响到其他元素,可以使需要多次重排的元素脱离文档流来减少对其他元素的影响。
  4. 由于属性为 display: none 的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。所以,如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示,这样只在隐藏和显示时触发两次重排。

重绘 repaint:

第一次将渲染树中的每个节点转为实际的像素点绘制到屏幕上,称为绘制;之后重新渲染,称为重绘。

引发重绘的操作:修改元素的外观,例如文字颜色、背景颜色、边框样式等。

浏览器的 Composite 合成:

浏览器在 Painting 绘制的过程中,还可以进行 Composite 合成,这是浏览器提供的一种优化手段。

浏览器可以将布局后的元素绘制到多个图层中。videocanvasiframe 元素,设置了 position: fiexed3D transformsanimation、trasnition 时设置 opacity、transformwill-change(一个实验性的属性。提前告诉浏览器元素可能发生哪些变化) 属性的元素,都会被绘制到一个新的合成层中。而其他的元素都会被绘制在同一个图层中。

合成层可以提升性能,因为每个合成图层都是单独渲染的;并且会交给 GPU 来处理,比 CPU 更快;而且当需要重绘时,合成层只需要重绘本身,不会影响到其他的图层。

可以在 chrome 开发者工具中查看图层。
在这里插入图片描述

<style>
	.box {
		width: 100px;
		height: 100px;
	}
	.box1 {
		background: red;
	}
	.box2 {
		background: green;
		position: fixed;
	}
	.box3 {
		background: blue;
		position: fixed;
	}
</style>

<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>

可以看到有三个图层,其中两个是合成层。

请添加图片描述

对于有动画效果的元素,可以提升为合成层,来减少重绘对其他元素的影响,提升性能。虽然合层成确实可以在某种程度上提高性能,但是是以内存管理为代价的,不应作为 Web 性能优化策略的一种方式来过度使用。

<script> 元素和页面解析的关系:

默认情况下,在遇到 <script> 元素时,JS 的下载和执行会阻塞 HTML 的解析,只有下载好并执行完脚本才会继续解析 HTML。因为 JS 的作用之一就是操作 DOM,如果等到 DOM 树构建完成并渲染之后再执行 JS,JS 修改到 DOM 的话会造成严重的回流和重绘,影响页面的性能。

JS 的下载和解析会阻塞 HTML 的继续解析。
CSS 的下载和解析不会阻塞 HTML 的继续解析。

为了解决这个问题,除了可以将 <script> 元素放到 <body> 的最底部外,<script> 元素还提供了两个属性:defer 和 async。

  1. defer:只适用于外部脚本。JS 脚本会立即在新的线程中单独下载,不会阻塞 HTML 的解析;但是脚本下载完成后,不会立即执行,会等待 HTML 解析完成之后,DOMContentLoaded 事件发出之前再执行。多个脚本会按照在 HTML 文档中的顺序依次执行。
  2. async:只适用于外部脚本。JS 脚本会立即在新的线程中单独下载,不会阻塞 HTML 的解析;但是脚本下载完成后,会立即执行,此时会阻塞 HTML 的解析。多个脚本的执行顺序无法确定。

在设置了 defer 属性的 JS 文件中,访问到 DOM 元素一定是存在的;在设置了 async 属性的 JS 文件中,访问到 DOM 元素不一定存在。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值