浏览器渲染流程

我们在浏览网站的时候,从服务器返回html内容到呈现界面给用户的过程,浏览器需要经历以下流程:

  1. 处理HTML标记并构建DOM树。
  2. 处理CSS标记并构建CSSOM树。
  3. 将DOM与CSSOM合并成一个渲染树。
  4. 根据渲染树来布局,以计算每个节点的几何信息。
  5. 将各个节点绘制到屏幕上。

构建渲染树

构建渲染树,浏览器完成以下工作:

  • 从dom树的根节点遍历每个可见节点,在html中,scriptmeta等等会被忽略,不会渲染输出,display:none的节点也不会渲染
  • 适配cssom规则到每个可见节点

visibility: hidden 与 display: none 是不一样的。前者隐藏元素,但元素仍占据着布局空间(即将其渲染成一个空框),而后者 (display: none) 将元素从渲染树中完全移除,元素既不可见,也不是布局的组成部分。

要想构建渲染树,DOM 和 CSSOM 缺一不可。

布局

布局流程输出的是一个“盒模型”,浏览器可以精确每个元素在视图窗口的确切位置和尺寸,所有相对测量值都转换为屏幕上的绝对像素。

绘制

最后一步就是绘制(栅格化)阶段,浏览器将渲染树的每个节点转化为屏幕的实际像素,并绘制节点的内容和样式

提高浏览器渲染的注意事项

css资源的加载

CSS是阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。

通过CSS“媒体类型”和“媒体查询”来解决这类用例:

<link href="style.css" rel="stylesheet">
<link href="print.css" rel="stylesheet" media="print">
<link href="other.css" rel="stylesheet" media="(min-width: 40em)">

符合浏览器条件才会阻塞下载,上面最后一条在符合min-width:40em条件下下载,否则不下载

下面两条等效,默认就是all,无论什么情况下都会下载该css文件

<link href="style.css" rel="stylesheet">
<link href="style.css" rel="stylesheet" media="all">

第二条只在打印网页时应用,因此网页首次在浏览器中加载时,它不会阻塞渲染

<link href="print.css" rel="stylesheet" media="print">

“阻塞渲染”仅是指浏览器是否需要暂停网页的首次渲染,直至该资源准备就绪。无论哪一种情况,浏览器仍会下载CSS文件,只不过不阻塞渲染的资源优先级较低罢了

js资源的加载

无论我们使用<script>标记还是内联JavaScript代码段,您都可以期待两者能够以相同方式工作。 

在两种情况下,浏览器都会先暂停并执行脚本,然后才会处理剩余文档。不过,如果是外部JavaScript文件,浏览器必须停下来,等待从磁盘、缓存或远程服务器获取脚本,这就可能给关键渲染路径增加数十至数千毫秒的延迟。

默认情况下,所有JavaScript都会阻止解析器。由于浏览器不了解脚本计划在页面上执行什么操作,它会作最坏的假设并阻止解析器。向浏览器传递脚本不需要在引用位置执行的信号既可以让浏览器继续构建DOM,也能够让脚本在就绪后执行;

例如,在从缓存或远程服务器获取文件后执行。可以在主script文件里面添加async标志,向script标记添加async关键字可以指示浏览器在等待脚本可用期间不阻止DOM构建,这样可以显著提升性能。