23 渲染流水线,css如何影响首次白屏的时间?

您所在的位置:网站首页 DOM手表怎么调时间 23 渲染流水线,css如何影响首次白屏的时间?

23 渲染流水线,css如何影响首次白屏的时间?

2023-05-29 11:29| 来源: 网络整理| 查看: 265

继续深入聊聊渲染流水线中的CSS。因为CSS是⻚面中非常重要的资源,它决定了⻚面最终显示出来的效果,并影响着用戶对整个网站的第一体验。所以,搞清楚浏览器中的CSS是怎么工作的很有必要,只有理解了CSS是如何工作的,你才能更加深刻地理解如何去优化⻚面。

渲染流水线视⻆下的CSS

//theme.css div{ color : coral; background-color:black } geekbang com

截屏2023-05-15 上午9.47.25.png

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

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

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

和HTML一样,渲染引擎也是无法直接理解CSS文件内容的,所以需要将其解析成渲染引擎能够理解的结构,这个结构就是CSSOM。和DOM一样,CSSOM也具有两个作用,第一个是提供给JavaScript操作样式表,第二个是为布局树的合成提供基础的样式信息。

这个CSSOM体现在DOM中就是document.styleSheets。

有了DOM和CSSOM就可以构造布局树了。

布局树的结构基本上就是复制DOM树的结构,不同之处在于DOM树中那些不需要显示的元素会被过滤掉display:none属性的元素、head标签、script标签等

复制好基本的布局树结构之后,渲染引擎会为对应的DOM元素选择对应的样式信息,这个过程就是样式计算样式计算。样式计算完成之后,渲染引擎还需要计算布局树中每个元素对应的几何位置,这个过程就是计算布局

通过样式计算和计算布局就完成了最终布局树的构建。再之后,就该进行后续的绘制操作了

//theme.css div{ color : coral; background-color:black } geekbang com console.log('time.geekbang.org') geekbang com

截屏2023-05-15 上午10.43.36.png

首先下载html 然后解析html 下载css 构建cssom 因为js依赖cssom js又阻塞dom解析所以要等待cssom完事儿 js 跑才能继dom解析在布局树。

那我们就结合这张图来分析含有外部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') geekbang com geekbang com

截屏2023-05-15 上午11.01.20.png

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

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

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

第一个阶段,等请求发出去之后,到提交数据阶段,这时⻚面展示出来的还是之前⻚面的内容。关于提交数据你可以参考前面《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是如何影响到渲染流程的;接下来我们通过渲染流水线分析了从发出请求到⻚面首次绘制的三个阶段;最后重点介绍了第二个白屏阶段以及优化该阶段的一些策略。

1: 2: 3: 4: 5: 6: 7: 8:

第1条:下载JavaScript文件并执行同步代码,会阻塞⻚面渲染

第2条:defer异步下载JavaScript文件,会在HTML解析完成之后执行,不会阻塞⻚面渲染

第3条:sync异步下载JavaScript文件,下载完成之后会立即执行,有可能会阻塞⻚面渲染

第4条:下载CSS文件,可能阻塞⻚面渲染

第5条:media属性用于区分设备,screen表示用于有屏幕的设备,无法用于打印机、3D眼镜、盲文阅读机等,在题设手机条件下,会加载,与第4条一致,可能阻塞⻚面渲染

第6条:print用于打印预览模式或打印⻚面,这里不会加载,不会阻塞⻚面渲染

第7条:orientation:landscape表示横屏,与题设条件一致,会加载,与第4条一致,可能阻塞⻚面渲染

第8天:orientation:portrait表示竖屏,这里不会加载,不会阻塞⻚面渲染

JavaScript脚本需要使用到CSSOM能力的时候才会有这个前置依赖



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3