浏览器接收 这三种文件,渲染出页面
HTML:HyperText Marked Language, 超文本标记语言, 标记 和 文本 组成
CSS: Cascading Style Sheets, 层叠样式表, 选择器 和 属性组成
JS: Javascript, 解释型编程语言, 能让页面'动'起来
渲染流水线分为以下8个子阶段:
构建DOM树 样式计算 布局阶段 分层 绘制 分块 光栅化 合成
创建出节点
1.HTML被转换为浏览器能理解的结构,DOM树
根据HTML中的 层次结构,将HTML解析为 具有父子节点关系的DOM树
浏览器输入document可以看到DOM树结构
计算出每个节点的样式
2.将CSS转换为浏览器能理解的结构,styleSheets
CSS三个来源link外部CSS文件,style标签内的CSS,元素style属性内的CSS
该结构具备查询和修改功能
浏览器输入document.styleSheets查看
3.转换样式表中的属性值,使其标准化
如:2em,blue,bold等属性值
4.计算出DOM树中每个节点的具体样式(继承和层叠)
继承:子节点继承父节点样式,层叠:一个DOM节点合并多个来源属性值的优先级
计算出DOM树中 可见元素 的 几何位置
5.创建布局树
构建只含可见元素的布局树,如 head标签下的全部内容全不可见
6.布局计算
进行布局操作的时候,会把布局运算的结构又写回布局树
所以布局树既是输入又是输出,这是布局阶段一个不合理的地方
Chrome团队正在重构代码,下一代布局系统叫LayoutNG,试图清晰分离输入输出,布局算法更加简单
一个图层可包含多个节点,满足以下情况之一会生成图层
拥有层叠上下文属性的元素会单独一层(position:fixed,z-index,opacity:0.5)
被裁剪过的元素,如 div盒子长宽小于内容长宽
渲染引擎将一个图层的绘制分成多个绘制指令,组成待绘制列表
绘制列表 只是用来记录 绘制顺序 和 绘制指令 的列表,
主线程将绘制列表提交给合成线程,实际绘制由 渲染引擎 中的 合成线程 来完成
视口(viewport):用户能看见的页面部分,
图块(tile):栅格化的最小单位,256X256或512X512,合成线程 将图层分化而来
栅格化/光栅化: 将 图块 转化为 位图
快速栅格化/GPU栅格化: 栅格化在专门的 栅格化线程池 中执行, 通常使用GPU生成位图,
结果的位图数据 在GPU内存中,这就涉及了跨进程操作,渲染进程 与 GPU进程
合成线程 将图层分为图块
图块在 栅格化线程池中 被栅格化 为位图
合成线程 在所有图块被光栅化后, 生成 绘制图块命令DrawQuad,提交 浏览器线程
浏览器线程, viz组件 接收 DrawQuad命令, 将页面内容绘制在 内存 中,最后将 内存 显示在屏幕上
浏览器接收到HTML页面第一批数据的时候,DOM解析器开始工作
JS脚本会阻塞DOM渲染
JS外部脚本也会阻塞DOM渲染
JS脚本访问了元素样式,则会等待样式文件下载,从而阻塞DOM渲染
如果,解析过程遇到内部JS脚本非文件,会暂停解析,执行JS脚本,再继续解析;
如果,解析过程遇到外部JS脚本文件,会暂停解析,下载并执行JS脚本,再继续解析;
如果,解析过程遇到JS脚本,会暂停解析,执行JS脚本,
如果,此JS脚本访问了某元素样式,会暂停JS执行,等待样式下载,才继续执行JS.