首页 > 其他分享 >浏览器工作原理与实践--渲染流水线:CSS如何影响首次加载时的白屏时间

浏览器工作原理与实践--渲染流水线:CSS如何影响首次加载时的白屏时间

时间:2024-04-09 18:31:42浏览次数:29  
标签:文件 渲染 -- JavaScript 流水线 白屏 CSS 页面

在上一篇文章中我们详细介绍了DOM的生成过程,并结合具体例子分析了JavaScript是如何阻塞DOM生成的。那本文我们就继续深入聊聊渲染流水线中的CSS。因为CSS是页面中非常重要的资源,它决定了页面最终显示出来的效果,并影响着用户对整个网站的第一体验。所以,搞清楚浏览器中的CSS是怎么工作的很有必要,只有理解了CSS是如何工作的,你才能更加深刻地理解如何去优化页面。

本文我们先站在渲染流水线的视角来介绍CSS是如何工作的,然后通过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>

这两段代码分别由CSS文件和HTML文件构成,我们来分析下打开这段HTML文件时的渲染流水线,你可以先参考下面这张渲染流水线示意图:

含有CSS的页面渲染流水线

下面我们结合上图来分析这个页面文件的渲染流水线。

含有CSS的页面渲染流水线

下面我们结合上图来分析这个页面文件的渲染流水线。

首先是发起主页面的请求,这个发起请求方可能是渲染进程,也有可能是浏览器进程,发起的请求被送到网络进程中去执行。网络进程接收到返回的HTML数据之后,将其发送给渲染进程,渲染进程会解析HTML数据并构建DOM。这里你需要特别注意下,请求HTML数据和构建DOM中间有一段空闲时间,这个空闲时间有可能成为页面渲染的瓶颈。

上一篇文章中我们提到过,当渲染进程接收HTML文件字节流时,会先开启一个预解析线程,如果遇到JavaScript文件或者CSS文件,那么预解析线程会提前下载这些数据。对于上面的代码,预解析线程会解析出来一个外部的theme.css文件,并发起theme.css的下载。这里也有一个空闲时间需要你注意一下,就是在DOM构建结束之后、theme.css文件还未下载完成的这段时间内,渲染流水线无事可做,因为下一步是合成布局树,而合成布局树需要CSSOM和DOM,所以这里需要等待CSS加载结束并解析成CSSOM。

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

和HTML一样,渲染引擎也是无法直接理解CSS文件内容的,所以需要将其解析成渲染引擎能够理解的结构,这个结构就是CSSOM。和DOM一样,CSSOM也具有两个作用,第一个是提供给JavaScript操作样式表的能力,第二个是为布局树的合成提供基础的样式信息。这个CSSOM体现在DOM中就是document.styleSheets。具体结构你可以去查阅相关资料,这里我就不过多介绍了,你知道CSSOM的两个作用是怎样的就行了。

有了DOM和CSSOM,接下来就可以合成布局树了,我们在前面《05 | 渲染流程(上):HTML、CSS和JavaScript文件,是如何变成页面的?》这篇文章中讲解过布局树的构造过程,这里咱们再简单回顾下。等DOM和CSSOM都构建好之后,渲染引擎就会构造布局树。布局树的结构基本上就是复制DOM树的结构,不同之处在于DOM树中那些不需要显示的元素会被过滤掉,如display:none属性的元素、head标签、script标签等。复制好基本的布局树结构之后,渲染引擎会为对应的DOM元素选择对应的样式信息,这个过程就是样式计算。样式计算完成之后,渲染引擎还需要计算布局树中每个元素对应的几何位置,这个过程就是计算布局。通过样式计算和计算布局就完成了最终布局树的构建。再之后,就该进行后续的绘制操作了。

这就是在渲染过程中涉及到CSS的一些主要流程。

了解了这些之后,我们再来看看稍微复杂一点的场景,还是看下面这段HTML代码:

//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>

这段代码是我在开头代码的基础之上做了一点小修改,在body标签内部加了一个简单的JavaScript。有了JavaScript,渲染流水线就有点不一样了,可以参考下面这张渲染流水线图:

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

那我们就结合这张图来分析含有外部CSS文件和JavaScript代码的页面渲染流水线,上一篇文章中我们提到过在解析DOM的过程中,如果遇到了JavaScript脚本,那么需要先暂停DOM解析去执行JavaScript,因为JavaScript有可能会修改当前状态下的DOM。

不过在执行JavaScript脚本之前,如果页面中包含了外部CSS文件的引用,或者通过style标签内置了CSS内容,那么渲染引擎还需要将这些内容转换为CSSOM,因为JavaScript有修改CSSOM的能力,所以在执行JavaScript之前,还需要依赖CSSOM。也就是说CSS在部分情况下也会阻塞DOM的生成。

我们再来看看更加复杂一点的情况,如果在body中被包含的是JavaScript外部引用文件,Demo代码如下所示:

//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>

从上面代码可以看出来,HTML文件中包含了CSS的外部引用和JavaScript外部文件,那它们的渲染流水线是怎样的呢?可参考下图:

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

从图中可以看出来,在接收到HTML数据之后的预解析过程中,HTML预解析器识别出来了有CSS文件和JavaScript文件需要下载,然后就同时发起这两个文件的下载请求,需要注意的是,这两个文件的下载过程是重叠的,所以下载时间按照最久的那个文件来算。

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

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

前面我们为什么要花这么多文字来分析渲染流水线呢?主要原因就是渲染流水线影响到了首次页面展示的速度,而首次页面展示的速度又直接影响到了用户体验,所以我们分析渲染流水线的目的就是为了找出一些影响到首屏展示的因素,然后再基于这些因素做一些针对性的调整。

那么接下来我们就来看看从发起URL请求开始,到首次显示页面的内容,在视觉上经历的三个阶段。

  • 第一个阶段,等请求发出去之后,到提交数据阶段,这时页面展示出来的还是之前页面的内容。关于提交数据你可以参考前面《04 | 导航流程:从输入URL到页面展示,这中间发生了什么?》这篇文章。

  • 第二个阶段,提交数据之后渲染进程会创建一个空白页面,我们通常把这段时间称为解析白屏,并等待CSS文件和JavaScript文件的加载完成,生成CSSOM和DOM,然后合成布局树,最后还要经过一系列的步骤准备首次渲染。

  • 第三个阶段,等首次渲染完成之后,就开始进入完整页面的生成阶段了,然后页面会一点点被绘制出来。

影响第一个阶段的因素主要是网络或者是服务器处理这块儿,前面文章中我们已经讲过了,这里我们就不再继续分析了。至于第三个阶段,我们会在后续文章中分析,所以这里也不做介绍了。

现在我们重点关注第二个阶段,这个阶段的主要问题是白屏时间,如果白屏时间过久,就会影响到用户体验。为了缩短白屏时间,我们来挨个分析这个阶段的主要任务,包括了解析HTML、下载CSS、下载JavaScript、生成CSSOM、执行JavaScript、生成布局树、绘制页面一系列操作。

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

所以要想缩短白屏时长,可以有以下策略:

  • 通过内联JavaScript、内联CSS来移除这两种类型的文件下载,这样获取到HTML文件之后就可以直接开始渲染流程了。

  • 但并不是所有的场合都适合内联,那么还可以尽量减少文件大小,比如通过webpack等工具移除一些不必要的注释,并压缩JavaScript文件。

  • 还可以将一些不需要在解析HTML阶段使用的JavaScript标记上sync或者defer。

  • 对于大的CSS文件,可以通过媒体查询属性,将其拆分为多个不同用途的CSS文件,这样只有在特定的场景下才会加载特定的CSS文件。

通过以上策略就能缩短白屏展示的时长了,不过在实际项目中,总是存在各种各样的情况,这些策略并不能随心所欲地去引用,所以还需要结合实际情况来调整最佳方案。

总结

好了,今天就介绍到这里,下面我来总结下今天的内容。

我们首先介绍了CSS在渲染流水线中的位置,以及CSS是如何影响到渲染流程的;接下来我们通过渲染流水线分析了从发出请求到页面首次绘制的三个阶段;最后重点介绍了第二个白屏阶段以及优化该阶段的一些策略。

通过今天的内容我们可以知道虽然JavaScript和CSS给我们带来了极大的便利,不过也对页面的渲染带来了很多的限制,所以我们要关注资源加载速度,需要小心翼翼地处理各种资源之间的关联关系。

标签:文件,渲染,--,JavaScript,流水线,白屏,CSS,页面
From: https://blog.csdn.net/echohuangshihuxue/article/details/137539315

相关文章

  • 【C语言中的操作符详解】
    目录一 C语言中的操作符详解:1.算术操作符2.关系操作符(比较操作符)3.逻辑操作符4.位操作符5.赋值操作符6.条件(三元)操作符7.其他操作符8.递增和递减操作符二c语言操作符,应用场景:算术操作符:位操作符:关系操作符:逻辑操作符:赋值操作符:条件(三元)操作符:其他......
  • 汇编语言和C语言得优势和劣势简析
    汇编语言和C语言各自具有不同的优势和劣势,适用于不同的编程场景和需求。以下是对两者的一些比较:汇编语言的优势:硬件接近性:汇编语言直接对应机器指令,可以精确控制硬件,非常适合底层硬件编程和系统级编程。例如,在编写操作系统内核、设备驱动程序或实时系统时,汇编语言可以确保对......
  • C语言--extern关键字介绍
    在C语言中,extern关键字用于声明一个变量或函数是在其他地方定义的,而不是在当前文件中。它告诉编译器,变量的定义或函数的实现在其他地方,这样编译器就不会在当前编译单元中查找它们的定义。这样做的好处是可以将一个大型程序分割成多个源文件,每个源文件可以单独编译,最后链接成一......
  • C++程序分享--常见编程面试题:判断字符串是否为回文串
    关注我,持续分享逻辑思维&管理思维;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;有意找工作的同学,请参考博主的原创:《面试官心得--面试前应该如何准备》,《面试官心得--面试时如何进行自我介绍》, 《做好面试准备,迎接2024金三银四》。【图解《程序员面试常见的十大算法......
  • 如何删除window10此电脑下的“视频/文档/音乐“等文件夹方法
    按下win+r,输入regedit回车,打开注册表。然后在导航栏里输入HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace2、找到相应的键值进行修改操作:(1)更改【下载】文件夹:{088e3905-0323-4b02-9826-5d99428e115f}(2)更改【图片】......
  • sklearn之average_precision_score计算返回NaN
    问题描述使用sklearn计算AP时,当label全是负标签时会返回NaN,例如:>>>importnumpyasnp>>>fromsklearn.metricsimportaverage_precision_score>>>average_precision_score(np.array([0,0,0,0,0]),np.array([0.1,0.1,0.1,0.1,0.1]))xxx/lib/pytho......
  • TME Studio:音乐创作的得力助手
    一、TMEStudio——开启智能音乐创作新纪元官网链接曾几何时,音乐创作的梦想似乎遥不可及,而如今,腾讯音乐娱乐集团推出的TMEStudioAI音乐创作工具,让这一切变得触手可及。它如同一位随身的作曲大师,随时为你谱写美妙旋律;又像一把魔法棒,轻轻一挥,就能为你的歌曲增添丰富的编曲......
  • html中image 区域点击的优点
    在HTML中,图像(image)区域可以被用作交互元素,通过点击操作可以实现多种功能和优点。以下是点击图像区域的一些优点:用户友好的交互:图像是一种直观的视觉元素,用户很容易理解和与之交互。点击图像可以触发预定义的动作或事件,如导航到另一个页面、放大图片、播放视频等,这提供了一......
  • 招投标02-招标文件(标前准备阶段)
    ###################################################前面我们说明了招投标的流程,按照规划内容,本节补齐在标前准备阶段的最后一块:招标文件。01-招投标流程总结详见:https://www.cnblogs.com/hemukg/p/1811211602-招标文件说明在标前准备阶段,招标文件有哪些内容,哪些内容需要注......
  • (亲测好用)使用PHP提取PDF内容的详细步骤与实例
    使用PHP提取PDF内容的详细步骤与实例在现代Web开发中,处理PDF文件的需求越来越普遍。无论是需要读取PDF文件的内容,还是需要进行PDF文件的编辑和转换,PHP都提供了丰富的库和函数来帮助我们完成这些任务。本文将详细介绍如何使用PHP来提取PDF文件的内容,并提供相关的代码示例。1.安装......