【14】winter重学前端 笔记 – 浏览器:一个浏览器是如何工作的?(阶段五)渲染

20次阅读

共计 1307 个字符,预计需要花费 4 分钟才能阅读完成。

回顾
URL-> 字符流 -> 词流 (token)->DOM 树 -> 包含样式信息的 DOM 树 - 计算了每个元素的位置和大小 (排版)
渲染

定义:把元素变成位图的过程(每一个元素对应的盒变成位图,一个元素可能对应多个盒(比如 inline 元素,可能分成多行)
位图:在内存里建立一张二维表格,把一张图片的每个像素对应的颜色保存进去(位图信息也是 DOM 树中占据浏览器内存最多的信息,我们在做内存占用优化时,主要就是考虑这一部分)

分类:图形和文字

图形类:盒的背景、边框、SVG 元素、阴影等特性
盒的特性如何绘制,每一个都有对应的标准规定,不详细探究

文字类
分类:分为像素字形和矢量字形(会在 6px 8px 等小尺寸提供像素字形,比较大的尺寸则提供矢量字形)

最普遍的情况下,渲染过程生成的位图尺寸跟它在上一步排版时占据的尺寸相同,很多属性会影响渲染位图的大小,比如阴影,为了优化,浏览器实际的实现中会把阴影作为一个独立的盒来处理
一般的操作系统会提供一个底层库来支持渲染:Android(Skia)Windows(GDI) 浏览器会做一个兼容层来处理掉平台差异
渲染过程:不会把子元素绘制到渲染的位图上的,当父子元素的相对位置发生变化时,可以保证渲染的结果能够最大程度被缓存,减少重新渲染
输入框实现:渲染过程除了位图,最终绘制上去还产生一个 ” 热区 ”,这个“热区”不但跟你说的 input 相关,还跟用户选择、鼠标事件和 scroll 等交互相关 (太复杂啦,winter 没有讲)

合成

定义:为一些元素创建一个“合成后的位图”(我们把它称为合成层),把一部分子元素渲染到合成的位图上面,性能优化行为,非浏览器必须

合成的策略:最大限度减少绘制次数,“猜测”可能变化的元素,把它排除到合成之外

主流浏览器一般根据 position、transform 等属性来决定合成策略,来“猜测”这些元素未来可能发生变化
新的 CSS 标准中,规定了 will-change 属性,可以由业务代码来提示浏览器的合成策略
????

合成策略能够把 a、b 两个 div 合成,而不把 c 合成
在实际场景中,我们的 b 可能有很多复杂的子元素,所以当合成命中时,性能提升收益非常之高
<div id=”a”>
<div id=”b”>…</div>
<div id=”c” style=”transform:translate(0,0)”></div>
</div>

document.getElementById(“c”).style.transform = “translate(100px, 0)”;

绘制

定义:把“位图最终绘制到屏幕上,变成肉眼可见的图像”的过程,实际上就是按照 z-index 把它们依次绘制到屏幕
浏览器不处理,把要显示的位图交给操作系统

限制绘制的面积 (换一个角度理解重绘 repaint):

问题:鼠标划过浏览器显示区域。这个过程中,鼠标的每次移动,都造成了重新绘制,如果我们不重新绘制,就会产生大量的鼠标残影
解决:“脏矩形”算法 – 把屏幕均匀地分成若干矩形区域,重新绘制脏矩形区域时,把所有与矩形区域有交集的合成层(位图)的交集部分绘制即可。

作业:
用 JavaScript 实现一个玩具浏览器 (用 canvas 模拟一个 iframe 吗)

正文完
 0