简介
渲染原理、优化 密不可分
渲染 render
html字符串 => 渲染 => 像素信息
浏览器如何渲染页面
vue、reactor => virtual dom => dom diff => 渲染
网络线程:html => 【渲染任务入队】 => 渲染主线程:渲染
1、解析HTML - Parse HTML
DOM(Document Object Model 文档对象模型)
CSSOM(CSS Object Model CSS对象模型)
dom树,后续被js操作(js 是对 c++ 的包装)
html字符串 => parseHTML => DOM树、CSSOM树
2、样式计算 - Recalculate Style
样式计算
em 转 px
父red 子black,那么 子就是black。
有些算不出来,要布局好才能算:百分比
3、布局 - Layout
【1、内容必须在行盒中】
【2、行盒和块盒不能相邻】
行级元素、块级元素 是指 HTML,html只提供语义化,
行盒 块盒 是指css。
4、分层 - Layer
分层:操作的时候,不能把浏览器重新渲染一遍,例如:只修改一层就行了。
堆叠上下文有关的属性:会印象分层的决策 z-index,opacity,transform,…
5、绘制 - Paint
【主线程】
parse:解析HTML,生产DOM树,CSSOM树
style:计算样式,生产带有样式的DOM树
layout:布局,生成每个节点的几何信息(布局树 和 DOM树有差异,会不一样)
layer:布局树 进行分层
paint:绘制,对每一层生成绘制指令(几何信息都知道了,就知道怎么去画了)
6、分块 - Tiling
分块:这里就不是主线程了,是合成线程做分块。
7、光栅化 - Raster
分块:块有多少像素点(几何信息),每个像素点的信息-颜色(位图),
GPU:只做和显示相关的事情,做得事情更专注,做的更快(比CPU快)。
布局:相对整个页面的
quad:位图相对的屏幕在哪儿,先画哪个位图,再画哪个位图,
draw quad:quad信息交给GPU进程,GPU再交给硬件-显卡,最终显卡按照像素信息按照它的位置就呈现出来了。
为什么 合成线程 不直接交给硬件呢?还要交给 GPU进程去中转一下呢?
PS:GPU进程是浏览器的进程,不是显卡的。
合成线程、渲染主线程 在渲染进程中,而 渲染进程 放在沙盒中的,对硬件隔离(安全)。
防止浏览器遭受攻击,不会导致计算机中病毒。
而GPU进程不在沙盒中,可以访问硬件,所以要中转一下(为了安全,防止攻击)。
8、画 - Draw
第八步:画。确定 transform。
》》》 位图 通过 transform 进行矩阵变化,再 quad 交给 GPU。
完整过程
【渲染主线程】
1、解析:解析HTML,生成DOM树,CSSOM树
2、样式:计算样式,让每个DOM里面得到最终的样式
3、布局:计算出每个DOM节点的几何信息(布局树和DOM树不一样,不能对应)
4、分层:为了提高后续的渲染效率,把页面根据策略分成几个图层,每个层可以单独进行绘制
5、绘制:产生绘制指令,先画啥,再画啥
【合成线程】
6、分块:把绘制指令交给 合成线程的分块,
7、光栅化:对每个层的,每个小块进行光栅化,变成一个个像素点(位图-二维数组),优先光栅化靠近屏幕的小块,
8、画:最后,把小块发送给GPU画出来
reflow
width:300px 修改几何信息,修改的是 CSSOM。
如果创建DOM元素,影响布局。
re flow:重新布局,重新画一遍(flow排版,reflow重新排版)。
陶攀峰:为什么js放在最下面?
因为js会影响dom的加载,等渲染主进程全部执行完,再去搞js。
不然,等DOM还没渲染完整个HTML,执行js,需要重新渲染。
陶攀峰:为什么在js获取长宽,获取不到改变后的值?
因为执行js时,dom此时还没有重新渲染,js的整个8步还没有走完。
浏览器规定:获取属性,就会reflow。
repaint
reflow一定会导致repaint
transform
transform效率高的原因:改动样式,只影响2步: style(CSSOM树),draw。
transform + 动画:只影响1步:draw。
滚动条滚动:只影响1步:draw,重新把相对位置画一遍(主进程不参与,所以不影响滚动)。
2023-12-21 18:45:29 完结, 1小时50分钟视频记录。