前端性能优化 - 外部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

相关文章

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

小白也能轻松上手! 路由器设置优化指南

《小白也能轻松上手!路由器设置优化指南》在日常生活中,我们常常会遇到WiFi网速慢的问题,这主要受到三个方面的影响,首要原因是WiFi产品的配置优化不合理,其次是硬件性能的不足,以及宽带线路本身的质... 在数字化时代,网络已成为生活必需品,追剧、游戏、办公、学习都离不开稳定高速的网络。但很多人面对新路由器

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

Zabbix在MySQL性能监控方面的运用及最佳实践记录

《Zabbix在MySQL性能监控方面的运用及最佳实践记录》Zabbix通过自定义脚本和内置模板监控MySQL核心指标(连接、查询、资源、复制),支持自动发现多实例及告警通知,结合可视化仪表盘,可有效... 目录一、核心监控指标及配置1. 关键监控指标示例2. 配置方法二、自动发现与多实例管理1. 实践步骤

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon