当前位置:首页 > Web开发 > 正文

为什么发给显卡呢?我想有必要先聊一聊显示器显示图像的原理

2024-03-31 Web开发

上一节介绍了浏览器解析的过程,此中包罗构建DOM、样式计算和构建构造树。

接下来就来拆解下一个过程——衬着。分为以下几个法式:

成立图层树(Layer Tree)

生成绘制列表

生成图块并栅格化

显示器显示内容

一、建图层树

如果你感受此刻DOM节点也有了,样式和位置信息也都有了,可以开始绘制页面了,那你就错了。

因为你考虑失了此外一些庞大的场景,好比3D动画如何泛起出调动效果,当元素含有层叠上下文时如何控制显示和隐藏等等。

为了解决如上所述的问题,浏览器在构建完构造树之后,还会对特定的节点进行分层,构建一棵图层树(Layer Tree)。

那这棵图层树是按照什么来构建的呢?

一般情况下,节点的图层会默认属于父亲节点的图层(这些图层也称为合成层)。那什么时候会提升为一个单独的合成层呢?

有两种情况需要分袂讨论,一种是显式合成,一种是隐式合成

显式合成

下面是显式合成的情况:

一、 拥有层叠上下文的节点。

层叠上下文也根基上是有一些特定的CSS属性创建的,一般有以下情况:

HTML根元素自己就具有层叠上下文。

普通元素设置position不为static并且设置了z-index属性,会孕育产生层叠上下文。

元素的 opacity 值不是 1

元素的 transform 值不是 none

元素的 filter 值不是 none

元素的 isolation 值是isolate

will-change指定的属性值为上面任意一个。(will-change的感化后面会详细介绍)

二、需要剪裁的处所。

好比一个div,你只给他设置 100 * 100 像素的巨细,而你在里面放了非常多的文字,那么超过的文字部分就需要被剪裁。固然如果呈现了滚动条,那么滚动条会被单独提升为一个图层。

隐式合成

接下来是隐式合成,简单来说就是层叠品级低的节点被提升为单独的图层之后,那么所有层叠品级比它高的节点城市成为一个单独的图层。

这个隐式合成其实隐藏着巨大的危害,如果在一个大型应用中,当一个z-index对照低的元素被提升为单独图层之后,层叠在它上面的的元素统统城市被提升为单独的图层,可能会增加上千个图层,大大增加内存的压力,甚至直接让页面瓦解。这就是层爆炸的道理。这里有一个具体的例子,点击打开。

值得注意的是,当需要repaint时,只需要repaint自己,而不会影响到其他的层。

二、生成绘制列表

接下来衬着引擎会将图层的绘制拆分成一个个绘制指令,好比先画配景、再描绘边框......然后将这些指令按挨次组合成一个待绘制列表,相当于给后面的绘制操纵做了一波打算。

这里我以百度首页为例,大家可以在 Chrome 开发者工具中在设置栏中展开 more tools, 然后选择Layers面板,就能看到下面的绘制列表:

技术图片

三、生成图块和生成位图

此刻开始绘制操纵,实际上在衬着进程中绘制操纵是由专门的线程来完成的,这个线程叫合成线程

绘制列表筹备好了之后,衬着进程的主线程会给合成线程发送commit动静,把绘制列表提交给合成线程。接下来就是合成线程一展宏图的时候啦。

首先,考虑到视口就这么大,当页面非常大的时候,要滑很永劫间才华滑到底,如果要一口气全部绘制出来是相当浪费性能的。因此,合成线程要做的第一件工作就是将图层分块。这些块的巨细一般不会出格大,凡是是 256 * 256 或者 512 * 512 这个规格。这样可以大大加速页面的首屏展示。

因为后面图块数据要进入 GPU 内存,考虑到浏览器内存上传到 GPU 内存的操纵对照慢,即使是绘制一部分图块,也可能会耗费大量时间。针对这个问题,Chrome 给与了一个计谋: 在初度合成图块时只给与一个低辨别率的图片,这样首屏展示的时候只是展示出低辨别率的图片,这个时候继续进行合成操纵,,当正常的图块内容绘制完毕后,会将当前低辨别率的图块内容替换。这也是 Chrome 底层优化首屏加载速度的一个手段。

趁便提醒一点,衬着进程中专门维护了一个栅格化线程池,专门卖力把图块转换为位图数据

然后合成线程会选择视口相近的图块,把它交给栅格化线程池生成位图。

生成位图的过程实际上城市使用 GPU 进行加速,生成的位图最后发送给合成线程。

四、显示器显示内容

栅格化操纵完成后,合成线程会生成一个绘制命令,即"DrawQuad",并发送给浏览器进程。

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/32080.html