首页 > 其他分享 >浏览器的渲染流程

浏览器的渲染流程

时间:2022-11-16 19:33:43浏览次数:48  
标签:浏览器 DOM 流程 JavaScript 渲染 解析 绘制 CSS

1. 将 HTML 解析为 DOM 树

由于浏览器并不能理解 HTML 文件, 故而当网络进程将服务器返回的 HTML 传输给渲染进程时, 渲染进程也会逐步解析 HTML 文件, 构造一个浏览器能够理解的 DOM 树

2. 将 CSS 解析为 CSSOM 树

浏览器并不能理解 CSS 文件的内容, 故而当网络进程将服务器返回的 CSS 文件传输给渲染进程时, 渲染进程也会解析 CSS 文件, 构造一个 CSSOM 树, 并将对应的样式标准化, 使浏览器能够理解该内容

3. 合并 DOM 和 CSSOM 为布局树

4. 绘制

4.1 分层

4.1.1 渲染对象 Render Object

Render Object 上实现了将 DOM 绘制进位图的方法, 负责绘制 DOM 的可见内容. 每个 Render Object 和 DOM 节点一一对应, 且 Render Object 和 DOM 一样是树形的

4.1.2 渲染层 Render Layer

每一个 z-index 不同的层叠上下文元素(或被裁剪过的元素)划分为一个渲染层
而不是层叠上下文的元素(或者没有被裁剪过的元素)则会与离其最近的祖先层叠上下文元素共享同一个渲染层

4.1.3 合成层/图层 Graphics Layer 与 Graphics Context

当一个渲染层满足如下的常见条件时, 会被提升为 Graphics Layer

  • 3D transfroms: translate3d, translateZ 等
  • video, canva, iframe 等元素
  • 通过 Element.animate() 实现的 opacity 动画转换
  • 通过 CSS 动画实现的 opacity 动画转换
  • position: fixed
  • 具有 will-change 属性
  • 对 opacity, transform, fliter, backdropfilter 应用了 animation 或 transition

4.2 绘制图层

4.2.1 生成绘制列表

渲染进程会将一个图层的绘制拆分为很多小的绘制指令, 然后再将这些指令按照顺序组成一个待绘制列表

在浏览器中, 可以通过开发者工具查看:

生成完待绘制列表后, 渲染进程会将待绘制列表从主线程提交给其渲染进程中的合成线程

5. 合成

5.1 栅格化

有些图层可能会很大, 而用户又只能看到很小一部分. 如果直接对所有的图层进行绘制的话, 就会产生太大的开销, 而且也没有必要.
基于这个原因, 合成线程不会一次性就将图层绘制完毕, 而是优先绘制图层的一小部分(以视口为基准), 栅格化过程如下(栅格化操作通常会使用 GPU 进行加速完成)

  1. 合成线程将每个图层划分为多个图块(tile)
  2. 合成线程优先为可视图块生成位图, 当使用 GPU 加速时, 通常在 GPU 中生成位图, 生成的位图也保存在 GPU 的内存中

5.2 提升到合成层的好处

我们构造一个在页面中不断移动的元素

Code
<html>
<style>
@keyframes move{
  0%{
    top: 0;
    left: 0;
  }
  50%{
    top: 500px;
    left: 500px;
  }
  75%{
    top: 0;
    left: 400px;
  }
  100% {
    top: 400px;
    left: 0px;
  }
}
@keyframes opacity{
  0%{
    background-color: aliceblue;
  }
  50%{
    background-color: aqua;
  }
  100%{
    background-color:blueviolet;
  }
}

#composited{
  width: 200px;
  height: 200px;
  background: red;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 3;
}
.both{
  animation: move 1s infinite, opacity 1s infinite;
}
.move{
  animation: move 1s infinite;
}
</style>

<div  id="composited" class="both">
  composited - animation
</div>
</html>  

当将移动的元素提升到合成层时, 可以看到绘制次数(Paint Count)都只有一次


而该对应的元素没有提升到合成层时, 我们看到: 不仅 #document 的绘制次数大量增加, 而且 GPU 的内存占用也比之前多不少

6. 页面渲染的阻塞

6.1 CSS 阻塞页面的渲染

当对 CSS 解析没有完成时, DOM 无法与 CSSOM 形成 Layout Tree, 故而页面无法渲染

注: CSS 的解析和 HTML 的解析是同步进行的, CSSOM 的构建不会阻塞 DOM 的构建. 只是 CSSOM 没有构建完毕会使得 Layout Tree 的构建被阻塞, 最终表现为页面的展示被阻塞

6.2 JavaScript 阻塞页面的渲染

  1. 当 JavaScript 没有加载完成时, 因为 script 代码有可能会更改 DOM 树结构, 故而 HTML 并不会继续解析, 而是等待 JavaScript 代码执行完毕之后再进行解析
  2. JavaScript 代码加载完成之后需要等待 CSS 代码的加载完成, 因为 JavaScript 代码执行时可能要操作 Style 样式, 当 CSS 没有加载完成时, JavaScript 代码不会执行

解决方法:

  • 在 script 标签上添加 syncdefer 字段
    • sync: JavaScript 代码加载完成后, 立马执行对应的 JavaScript 代码
    • defer: JavaScript 代码加载完成后, 等待页面渲染完毕后再执行
  • 采用预解析线程: 当 HTML 代码中需要加载 JavaScript 或 CSS 时, 预解析线程会对这些文件进行提前下载

标签:浏览器,DOM,流程,JavaScript,渲染,解析,绘制,CSS
From: https://www.cnblogs.com/suzukaze/p/BrowserRender.html

相关文章

  • Android13.0的activity启动流程
    基于Android13.0相关源码:frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.javaActivityStarter.javaRootWindowContainer.j......
  • 接口测试的流程
    接口通俗的理解就是不同部分之间的连接通道,可以是程序之内的,也可以是不同程序之间的。一般公司都会要求做接口测试,因为这是测试前移和测试左移的一种方式,会极大的解决bug的......
  • (笔者推荐)【Java权威指南】「官方文档-中英互译」AQS的源码注释分析,贯穿总体核心流程
    前提说明本文主要针对于Java官方文档中的先关的官方注释进行中英文互译,保证了源码坐着的设计思路以及相关知识技能介绍分析等,本文主要进行介绍AQS的源码官方注释的含义介绍,......
  • Oracle11g RAC集群启动流程
    一、集群与资源启动顺序启动流程步骤层次梳理第一层:OHASD启动:cssdagent-负责启动CSSD的Agent。orarootagent-负责启动所有root用户下的ohasd资源的A......
  • 【tensorflow2.6】图片数据建模流程:猫狗分类,83.6%识别率
    目标:识别猫和狗一、猫狗数据集数据集下载:公众号,回复:猫狗数据集训练数据集(每一张图片都有dog和cat标签):测试集(图片没有标签):二、训练环境kaggletenslrflow2.6三、数据处理impo......
  • Cesium通过离屏渲染获取实现无人机侦察
    所需知识1、一定的WebGL原理,懂得帧缓冲区原理即FBO2、对Cesium源码有一定的研究原理创建飞机下方摄像机的视图,在Cesium渲染的时候,多获取一帧,把这一帧渲染到飞机下方视......
  • 渲染文案出现文字排版不齐、占位留空
    关于前端的结构层HTML最近大家说需要语义化(虽然全部用div也可以完成),我就本着语义化文案使用p标签让元素尽量清晰,结果如下:出现了排版不整齐问题,无论用displa......
  • 谷歌浏览器无法使用自带的谷歌翻译
    9月底谷歌关闭国内版翻译后,很多人用不了Chrome自带的全页翻译功能,我当时写了个教程:西柚秀:「技巧」Chrome浏览器自带谷歌翻译失效/用不了/打不开的解决方法之一263......
  • 可在浏览器端运行的Python
    转载自 涛哥聊Python半年前,知名Python发行版Anaconda开发商推出了 PyScript ——一款支持在浏览器中创建Python应用程序的框架。PyScript基于 Pyodide 构建,P......
  • 异步pyppeteer:并发运行多个浏览器并收集结果
    网上代码一大抄,居然网上讲pyppeteer异步的一大推,但运行起来都是await,并没有讲如何同时并发运行十几二个pyppeteer页面,那有个卵用呀,还不如开个多进程呢。话不多说,上代码。......