前端学习二
浏览器渲染过程
总过程
- html、css解析
- 样式计算
- 布局
- 分层
- 分块
- 绘制
- 光栅化
- 画
一 解析
html的来自页面的html代码或者网络请求返回的html代码。
html、css作为字符串,解析为树型结构的对象,便于用js操作。
html解析生成dom树,css解析生成cssom树。
样式表包括:
- 内部样式表 <style></style>
- 外部央视表 <link src=""/>
- 内联样式表 <div style=""></div>
- 浏览器默认样式表
浏览器默认样式表,谷歌浏览器为例:
js除了浏览器默认样式都能操作。
html dom 树
每个标签为一个节点,叶子节点为标签值。
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<p><button id="btn">TEST</button></p>
</body>
</html>
css cssom树
一个样式规则分为选择器和样式。
<style type="text/css">
p {
font-size: 20px;
}
#btn{
color: #123456;
}
</style>
解析过程
解析中遇到css样式表调用预解析线程异步加载和解析,提高解析效率,不会阻塞渲染主线程。
若外包样式表预解析线程调用网络线程下载,不影响渲染主线程。
遇到js代码会继续在渲染主线程执行,所以js加载慢会阻塞渲染主线程。
因为js可以操作dom树、cssom树,可能会修改html结构或者css样式,所以html、css解析过程必须暂停。
二 样式计算
生成dom树和cssom树后,解析过程中计算css属性值和视觉格式化。
计算css属性值:计算层叠(解决冲突后)、继承的值,得到每个节点的最终样式。
视觉格式化:包含盒模型,包含块,流式布局等。
预设值变为觉得值(red变为rgb(255,0,0)),相对单位变为觉得单位(em变为px),最后建立每个节点带有样式的dom树。
三 布局
各种元素影响布局,比如css设定宽高、浮动,浏览器大小等,最后根据计算结果再生成树,即Layout树。
元素位置都相对于包含块。
经过遍历dom树,布局计算后的树,与原本的dom数结构不同。
两者不是一一对应,差异开源与隐藏元素。
差异原因:
- Layout树的作用是找到每个节点的几何信息(尺寸和位置),会加入隐藏元素,比如不显示的节点,或css伪类选择器(::after等)。
- 根据内容(元素)必须在行盒、行盒块盒不能相邻,会根据情况加块盒行盒。
<div>
<div>test</div>
test
</div>
Layout树中不是js对象,但是js可以获取布局树种的信息,即js获取布局的几何信息,比如屏幕宽高、div宽高等。
四 分层
浏览器优化,便于及时响应变化。
将页面分层,改动仅影响对应的分层。
一般不会分太多层,因为每个层都会占用内存,不同浏览器不同版本策略不同。
涉及分层属性:z-index、opacity、transform、will-change等。
will-change适用于页面频繁改变,优化渲染用,会影响分层数量。
五 分块
分块将每一层分为多个小的区域,便于分优先级执行。
六 绘制
生成绘制指令。
类似于js的canvas,先设置绘制的代码,最后执行绘制。
主线程将每个图层的绘制信息交给合成线程,剩余工作由合成线程完成,渲染主线程不再参与执行。
八 光栅化
GPU进程将每个块变成位图,优先处理靠近视口区域的块。
通过到GPU加速,提高光栅化速度。
生成位图后,交给合成进程。
九 画
合成线程根据块和位图,生成指引信息,交给GPU进程。
指引信息会标识出每个位图在屏幕中的位置,以及旋转缩放变形等。
GPU进程将信息交给显卡,显示最终结果。
渲染主线程、合成线程都在渲染进程中,渲染进程在沙盒中,和操作系统硬件隔离。
通过浏览器GPU进程,调用硬件。
因为渲染进程在沙盒中,提高浏览器的安全。
附加
transform
在GPU进程中运行,不在主线程中运行。
css改动样式,不影响整个绘制过程。
<div class="an_div">
<div class="kuai"></div>
</div>
.kuai{
width: 10px;
height: 10px;
background-color: #123312;
animation-name: kuai;/*动画名*/
animation-duration : 1s;/*执行时间*/
animation-timing-function : ease;/*执行速度曲线*/
animation-iteration-count:infinite;/*执行次数 无限*/
animation-direction:alternate;/*执行正向或者反向 动画每次完成后反向播放*/
}
.an_div{
width: 500px;
height: 50px;
background-color: #efefef;
padding: 1em;
}
@keyframes kuai {
to{
transform: translate(100px);
}
}
reflow
js修改,修改几何信息时修改cssom树,修改标签节点修改dom树,都会导致重绘。
其本质是重新计算layout树。
连续js修改操作,浏览器会合并操作,目的是提升效率,读取几何信息时会被立即执行。
repaint 重绘
根据分成信息计算绘制指令。
改动内容不影响layout树,比如字体颜色、背景信息等,重新绘制。
参考
https://developer.mozilla.org/zh-CN/docs/Web/API/CSS_Object_Model
https://www.cnblogs.com/talk-is-cheap/articles/15808326.html
包含块:习以为常但又不太了解的包含块——如何决定元素的尺寸和位置 - 鹏哥儿 - 博客园
will-change:【CSS】使用will-change来提高页面的渲染速度-阿里云开发者社区
animation:css学习_css ease-in-out-CSDN博客