浏览器原理 22 # 渲染流水线:CSS如何影响首次加载时的白屏时间?

Posted 凯小默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器原理 22 # 渲染流水线:CSS如何影响首次加载时的白屏时间?相关的知识,希望对你有一定的参考价值。

说明

浏览器工作原理与实践专栏学习笔记

渲染流水线视角下的 CSS

通过例子来看一下最简单的渲染流程:

//theme.css
div{ 
    color : coral;
    background-color:black
}
<html>
<head>
    <link href="theme.css" rel="stylesheet">
</head>
<body>
    <div>geekbang com</div>
</body>
</html>

渲染流水线示意图:

在这里插入图片描述

  • 请求 HTML 数据和构建 DOM 中间有一段空闲时间,这个空闲时间有可能成为页面渲染的瓶颈
  • 在 DOM 构建结束之后、theme.css 文件还未下载完成的这段时间内,渲染流水线处于空闲状态
  • 合成布局树需要 CSSOM 和 DOM,需要等待 CSS 加载结束并解析成 CSSOM

CSSOM

那渲染流水线为什么需要 CSSOM 呢?

和 HTML 一样,渲染引擎也是无法直接理解 CSS 文件内容的,所以需要将其解析成渲染引擎能够理解的结构,这个结构就是 CSSOM。

CSSOM 的作用

  1. 提供给 javascript 操作样式表的能力
  2. 为布局树的合成提供基础的样式信息

含有 JavaScript 和 CSS 的页面渲染流水线

//theme.css
div{ 
    color : coral;
    background-color:black
}
<html>
<head>
    <link href="theme.css" rel="stylesheet">
</head>
<body>
    <div>geekbang com</div>
    <script>
        console.log('time.geekbang.org')
    </script>
    <div>geekbang com</div>
</body>
</html>

在这里插入图片描述

如果页面中包含了外部 CSS 文件的引用,或者通过 style 标签内置了 CSS 内容,那么渲染引擎还需要将这些内容转换为 CSSOM。

CSS 在部分情况下也会阻塞 DOM 的生成。因为在执行 JavaScript 之前,还需要依赖 CSSOM。

含有 JavaScript 文件和 CSS 文件页面的渲染流水线

两个文件的下载过程是重叠的,所以下载时间按照最久的那个文件来算。

//theme.css
div{ 
    color : coral;
    background-color:black
}
//foo.js
console.log('time.geekbang.org')
<html>
<head>
    <link href="theme.css" rel="stylesheet">
</head>
<body>
    <div>geekbang com</div>
    <script src='foo.js'></script>
    <div>geekbang com</div>
</body>
</html>

在这里插入图片描述

不管 CSS 文件和 JavaScript 文件谁先到达,都要先等到 CSS 文件下载完成并生成 CSSOM,然后再执行 JavaScript 脚本,最后再继续构建 DOM,构建布局树,绘制页面。

影响页面展示的因素以及优化策略

从发起 URL 请求开始,到首次显示页面的内容,在视觉上经历的三个阶段:

  1. 第一个阶段:等请求发出去之后,到提交数据阶段,这时页面展示出来的还是之前页面的内容。
  2. 第二个阶段:提交数据之后渲染进程会创建一个空白页面,通常把这段时间称为解析白屏,并等待 CSS 文件和 JavaScript 文件的加载完成,生成 CSSOM 和 DOM,然后合成布局树,最后还要经过一系列的步骤准备首次渲染。
  3. 第三个阶段:等首次渲染完成之后,就开始进入完整页面的生成阶段了,然后页面会一点点被绘制出来。

影响第一个阶段的因素主要是:网络或者是服务器处理。影响第三个阶段后续在分析。

重点看一下第二个阶段。

这个阶段的主要问题是白屏时间,如果白屏时间过久,就会影响到用户体验。

怎么缩短白屏时间?

第二个阶段的主要任务包括了:解析 HTML、下载 CSS、下载 JavaScript、生成 CSSOM、执行 JavaScript、生成布局树、绘制页面一系列操作。

通常情况下的瓶颈主要体现在下载 CSS 文件、下载 JavaScript 文件和执行 JavaScript。

策略:

  1. 通过内联 JavaScript、内联 CSS 来移除这两种类型的文件下载,这样获取到 HTML 文件之后就可以直接开始渲染流程了。
  2. 但并不是所有的场合都适合内联,那么还可以尽量减少文件大小,比如通过 webpack 等工具移除一些不必要的注释,并压缩 JavaScript 文件。
  3. 还可以将一些不需要在解析 HTML 阶段使用的 JavaScript 标记上 async 或者 defer。
  4. 对于大的 CSS 文件,可以通过媒体查询属性,将其拆分为多个不同用途的 CSS 文件,这样只有在特定的场景下才会加载特定的 CSS 文件。

以上是关于浏览器原理 22 # 渲染流水线:CSS如何影响首次加载时的白屏时间?的主要内容,如果未能解决你的问题,请参考以下文章

CSS如何影响首次加载时的白屏时间

前端资源浏览器渲染原理

渲染原理

宏观视角下的浏览器:06 | 渲染流程(下):HTMLCSS和JavaScript,是如何变成页面的?

浏览器渲染基本原理:优化渲染性能

CSS的网络性能优化