前端性能优化 - 外部js和css加载对页面渲染首屏的影响

本文主要是介绍前端性能优化 - 外部js和css加载对页面渲染首屏的影响,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在开头,本文中的内容均为自己测试得到的结果,如有不正之处,还望指出!

开始今天的学习之前,先看一个概念。“页面渲染首屏”指的是什么?

首先我们要明确这个概念。首先给大家看一个图片(百度搜索引擎的页面的加载过程):


火焰图模块可以看到三条竖的虚线
蓝线代表DOM生成完毕,对应DOMContentLoaded event,
绿线代表第一次绘制的时间,
红色代表加载完成,对应load事件。

那么我们所说的是什么呢?我这里认为的是绿色线,然后我们再看一下绿色线页面渲染情况?


图中红色标注的原先是绿线,因为我鼠标放在上面的问题,变成了蓝色。我们现在看到的是就是没有百度大logo的样式(与图中左侧相比)。今天的主要是学习一些js和css的外部加载会对这个首屏加载时间有什么样的影响。(所有的测试基于chorme)

1. 外部js&css-script标签在head中

下面的例子可以访问外部js&css-script标签在head中,至于js文件和css文件就不贴出来了,可以再给的link中查看,css很简单,js是jquery文件。

<!Doctye html>
<html>
<head><link rel='stylesheet' href='./style.css' type='text/css'/><script type='text/javascript' src='./index.js'></script>
</head>
<body><div class='div'> Test dom load.</div>
</body>
</html>
还是和之前一样先贴出来performence中页面渲染的过程,由于图片比较大,可以点击图片放大查看。


图中有三个红色的圆框

第一个红色框
这里第一个主要是发送请求当前页面的请求以及拿到数据,具体的过程前面的文章已经说过了,这里就不一一在图中表明了。最后的step是一个p字母开头的蓝色区域,这里是parsehtml,也就是对于当前的页面解析,html的解析过程由上而下,解析到style标签是一个外部资源,于是发送请求css文件(图中parsehtml下方第一条竖线),继续解析到script同样也是外部资源,同样发送请求外部js文件(图中parsehtml下方第二条竖线)。

第二个红色框
是关于外部js&css的请求。

第三个红色框
第三个红色框的内容首先是加载执行js代码,然后才是构建构建DOM成功,接着是渲染页面,可以看到图中的绿色竖线已经是在最后面了,就是现在js(head内部)代码已经影响到页面渲染首屏的时间。


这里扯个闲篇

css的加载不会阻塞html的页面解析,因为如果阻塞的话,就不会在css资源还没有处理完的情况下,继续解析到script的标签。

那么对于js代码的执行会不会进行阻塞呢?
答案是会阻塞后面的js文件,为什么呢?这个呢其实可以看图中的第二个红色的圆框内,是关于请求外部资源js和css的,可以看到第三个圆框内的加载js代码是在第二个红色圆框的后面。js的加载执行是在css请求之后进行的。css的外部资源是会影响后面js代码的执行。

那么对于DOM树的构建呢?注意这里说的是DOM树的构建,答案请看本文第二章节。

对于Render的渲染肯定是会有阻塞的,因为Render树的构建需要CSSOM。


2. 外部js&css-script标签在body的结尾

下面的例子可以访问 外部js&css-script标签在body的结尾

<!Doctye html>
<html>
<head><link rel='stylesheet' href='./style.css' type='text/css'/>
</head>
<body><div class='div'> Test dom load.</div><script type='text/javascript' src='./index.js'></script>
</body>
</html>
同样把页面的performance过程贴出来

图中有三个红色框(第四个属于第二个红色框)。
第一个红色框
和上面的相同,就不在赘述。

第二个红色框
首先是进行css文件的加载,然后是进行Recalculate Style,Layout,Update Layer Tree,Paint,Composite Layers,进而渲染页面首屏,同样我们也看到了绿色竖线。

这里得到的结果是:位于body尾部的js外部文件不会对页面的首屏渲染进行影响,因为js的文件还没有加载。还在第三个红色框内部。

第三个红色框
加载执行js文件,并且重新计算样式,进行页面的渲染(这里的渲染应该是局部渲染,具体的内容还是需要到后面去学习,本章主要的内容还是在渲染首屏)。

同样扯个闲篇:

对于上面遗留的问题:css的加载会不会影响到DOM树的构建,这里我的理解是不会(可能出错,本人只是按照自己的想法说的)。因为从上面的图中看到,在第二个红色框内没有parseHtml的蓝色区域,如果有影响的话,这里应该会有一段蓝色区域去构建DOM树。当然如果chrome performence没有将构建DOM树的过程体现在火焰图中的,那就另当别论了。


3. 结论

从上面的两个例子看到的结果:
css的加载会对页面渲染首屏进行阻塞
js代码(位于head中)会对页面渲染首屏有阻塞,但是位于body标签最后的不会对于渲染首屏进行阻塞。当然,如果加载的js在css返回之前返回,那么js代码的执行会在渲染首屏之前进行执行,会对渲染首屏有阻塞


4. 闲篇defer & async

还是先回到上面的两个例子中去,最好可以点击到我给里的link中亲自去查看,会发现DOMContentLoad的时间都是在js执行之后才会执行的。

然后我们先看一下关于defer和async的介绍:

(1) 默认引用 script:<script type="text/javascript" src="x.min.js"></script>
当浏览器遇到 script 标签时,文档的解析将停止,并立即下载并执行脚本,脚本执行完毕后将继续解析文档。

(2) async模式 <script type="text/javascript" src="x.min.js" async></script>
当浏览器遇到 script 标签时,文档的解析不会停止,其他线程将下载脚本,脚本下载完成后开始执行脚本,脚本执行的过程中文档将停止解析,直到脚本执行完毕。

(3) defer模式 <script type="text/javascript" src="x.min.js" defer></script>
当浏览器遇到 script 标签时,文档的解析不会停止,其他线程将下载脚本,待到文档解析完成,脚本才会执行。

这里由于今天时间的关系,就不贴出图片了,具体的页面变化可以访问linkdefer,async,这里只是说当js在head标签内的情况。

这里就只说我看到的结果

当head内部js是async的时候,渲染页面首屏的时间会和将js放在body尾部的情况大致相同,不同的是DOMContentLoad的执行时间,可以看到DOMContentLoad执行的时间不在依赖于js脚本的执行是否完成,而是只依赖于DOM树的构建。如果是defer的情况下,会看到渲染初始首屏同样也不会依赖于js脚本的执行,但是和async不同的是DOMContentLoad的执行时间还是在js执行完成之后。

这二者之间的区别

js文件是否依赖于别人,如果依赖于别人,则可以使用defer,因为defer更符合我们的实际需求。对于async,个人其实没有想到用它的必要条件。主要原因是因为defer的执行按照在html自上而下的顺序执行的,但是async去不一定按照顺序执行。

这篇关于前端性能优化 - 外部js和css加载对页面渲染首屏的影响的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/325847

相关文章

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

Vuex Actions多参数传递的解决方案

《VuexActions多参数传递的解决方案》在Vuex中,actions的设计默认只支持单个参数传递,这有时会限制我们的使用场景,下面我将详细介绍几种处理多参数传递的解决方案,从基础到高级,... 目录一、对象封装法(推荐)二、参数解构法三、柯里化函数法四、Payload 工厂函数五、TypeScript

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

CSS will-change 属性示例详解

《CSSwill-change属性示例详解》will-change是一个CSS属性,用于告诉浏览器某个元素在未来可能会发生哪些变化,本文给大家介绍CSSwill-change属性详解,感... will-change 是一个 css 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化

CSS去除a标签的下划线的几种方法

《CSS去除a标签的下划线的几种方法》本文给大家分享在CSS中,去除a标签(超链接)的下划线的几种方法,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧... 在 css 中,去除a标签(超链接)的下划线主要有以下几种方法:使用text-decoration属性通用选择器设置:使用a标签选择器,将tex

前端高级CSS用法示例详解

《前端高级CSS用法示例详解》在前端开发中,CSS(层叠样式表)不仅是用来控制网页的外观和布局,更是实现复杂交互和动态效果的关键技术之一,随着前端技术的不断发展,CSS的用法也日益丰富和高级,本文将深... 前端高级css用法在前端开发中,CSS(层叠样式表)不仅是用来控制网页的外观和布局,更是实现复杂交