首页 > 其他分享 >前端性能----资源加载顺序

前端性能----资源加载顺序

时间:2022-12-20 14:00:13浏览次数:119  
标签:脚本 DOM 前端 阻塞 js ---- css 加载

渲染事件

           

前端性能----资源加载顺序_html

  1. **domLoading **表示开始解析第一批收到的 HTML 文档的字节
  2. **domInteractive **表示完成全部 HTML 的解析并且 DOM 构建完毕
  3. **domContentLoaded **表示 DOM 与 CSSOM 皆已准备就绪
  4. **domComplete **表示所有的处理都已完成并且所有的附属资源都已经下载完毕
  5. **loadEvent **作为网页加载的最后一步以便触发附加的应用逻辑

CSS阻塞

CSS会阻塞渲染树的构建,不阻塞DOM构建,但是在CSSOM构建完成之前,页面不会开始渲染(一片空白),与js不一样,js虽然会阻塞后续DOM构建,但是前面已经就绪的内容会进行渲染。CSS虽然不阻塞DOM构建,但是会阻塞后面js的执行,从而间接阻塞完整DOM的构建,举个例子:

在资源服务器端,设定css和js的返回延时,且js先返回,css后返回,但是文档中,css在js之前:

app.use('/css/:cssName',(req,res)=>{
let fileName = req.params.cssName;
setTimeout(()=>{
res.sendFile(fileName,{
root: path.join(__dirname,'../css')
});
},4000);
});

app.use('/js/:jsName',(req,res)=>{
let fileName = req.params.jsName;
setTimeout(()=>{
res.sendFile(fileName,{
root: path.join(__dirname,'../js')
});
},2000);
})

然后html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="/css/animateTop.css">
</head>
<body>
<p>body content before script</p>
<script type="text" src="/js/script1.js"></script>
<script type="texipt" src="/js/script3.js"></script>
<p>body after script</p>
</body>
</html>

测试发现,后边的js虽然先下载下来,但是只有等css执行完毕后,才得到执行。

然后进一步js又会阻塞后续DOM树构建,就这样导致整个渲染过程话费更多时间。所以我们要尽快加载CSS并构建CSSOM。

针对性优化

  • 尽早加载css文件并生成CSSOM.
  • 不使用@import
  • 利用媒体查询,处理特定设备下的CSS,以减少不必要的阻塞.

JS阻塞

JS默认也是会阻塞DOM和渲染树的构建的。HTML解析器在遇到脚本文件时,默认为停下来去获取脚本(不考虑资源预加载优化),然后执行,期间阻塞DOM构建。

defer脚本

声明为defer的脚本会延迟到DOM构建完成后(DOMInteractive事件),​​DOMContentLoaded​​​和​​window.onload​​事件之前执行(但依然会被浏览器的预加载策略提前下载)。只针对外联脚本有效。多个defer会按照先后顺序串行执行。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript" src="/js/script1.js" defer></script>
<script defer>
console.log('inserted');
</script>
</head>
<body>
<script type="text/javascript" src="/js/script2.js"></script>
<p>conten after script</p>
<script>
document.addEventListener("DOMContentLoaded", function() {
console.log('DOMContentLoaded');
}, false);

window.addEventListener('load', function() {
console.log('window loaded');
}, false);
</script>
</body>
</html>

我们在控制台会看到先执行​​script2.js​​​其后面的p标签渲染没有受到阻塞。内联脚本按照正常顺序执行,依然阻塞DOM。它们都在​​DOMContentLoaded​​​和​​window.onload​​事件之前执行。

async脚本

声明 为异步的脚本会异步地下载和执行,会在window.onload事件之前执行,但是可能会在DOMContenLoaded事件前后执行。

一张图:


实际上上面的图并不完全正确。现代浏览器对脚本和样式资源还会有预加载策略。这个后面会讲。

多个defer和async脚本

当我们不使用defer和async,我们会看到现代浏览器的资源预加载策略会并行地下载多个脚本和样式文件:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="/css/animateTop.css">
</head>
<body>
<script type="text/javascript" src="/js/script1.js"></script>
<script type="text/javascript" src="/js/script2.js"></script>
<script type="text/javascript" src="/js/script3.js"></script>
<p>conten after script</p>
</body>
</html>

资源加载顺序:

​​

我们看到各个样式和脚本文件都是并行下载的,这得益于浏览器的资源预加载。

而当我们加入多个defer或者async时,情况有所变化,注意查看三个脚本的属性:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="/css/animateTop.css">
</head>
<body>
<script type="text/javascript" src="/js/script1.js" async></script>
<script type="text/javascript" src="/js/script2.js" async></script>
<script type="text/javascript" src="/js/script3.js"></script>
<p>conten after script</p>
</body>
</html>

资源加载顺序:

​​

我们发现第一个声明为async的script1和没有声明async的script3是和css同步加载的,而第二个声明为async的脚本即script2会排队,等待第一个async脚本加载完毕,defer也如此。

资源优先级

当我们网页上有许多图片,脚本和样式资源时,它们的加载顺序是怎样的呢?举个例子进行测试:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="/css/animateTop.css">
</head>
<body>
<img src="/images/img1.png"/>
<img src="/images/img2.png"/>
<img src="/images/img3.png"/>
<img src="/images/img4.png"/>
<script type="text/javascript" src="/js/script1.js"></script>
<script type="text/javascript" src="/js/script2.js"></script>
<script type="text/javascript" src="/js/script3.js"></script>
<p>conten after script1</p>
</body>
</html>

加载顺序:

​​

 

我们可以看到,样式和脚本的优先级是比图片更高的,因为这两个都具有阻塞性,浏览器让它们尽快下载下来。

第一个图片资源会和css一起下载,但浏览器发现后面还有许多图片就会优先去下载脚本文件。

 1.作者:Syw



标签:脚本,DOM,前端,阻塞,js,----,css,加载
From: https://blog.51cto.com/u_15739244/5954823

相关文章

  • git常用命令记录
    gitcheckoutbranchName切换分支gitswitchbranchName切换分支gitcheckout-bnewBranchName从当前分支拉去代码创建分支,并切换到新分支git......
  • JWT(生成Token令牌)
    .NetCore配置使用什么是JWT(详情在面试.md中有)JWT是目前最流行的跨域身份验证解决方案,JWT的原则是在服务器身份验证之后,会返回一个Json数据,,之后,当用户与服务器通信......
  • 保持 SSH 连接
    SSH总是被强行中断,尤其是用VSCode代码写的好好的,突然刷新窗口,不仅效率低,更惹人恼火。可以通过配置服务端或客户端的SSH来保持SSH链接:方法一:配置服务端可以在服务......
  • 编码字体与阅读字体推荐
    编码字体编码字体首要原则:等宽,等宽,还是TMD等宽!JetBrainsMonoHackSourceCodeProFiraMonoConsolas保底字体,基本上Windows电脑都有预装。阅读字体看多了......
  • 中国风?古典系?AI中文绘图创作尝鲜!⛵
    ......
  • 用C#同时开发计算机和手机的应用程序
    由于我在开发计算机的应用程序,使用的编程语言是C#,为了用一种语言同时开发计算机和手机的应用程序,我使用visualstudio2019在windows7操作系统上开发android应用程序。这样......
  • 你能谈谈HashMap怎样解决hash冲突吗
    在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样。当程序试图将多个key-value放入HashM......
  • 【过程】游戏王简单卡牌检索
    通过这样的代码显示我想要的内容aa=newa();while(hao==1){a.a();break;}这个是输入了名字之后会显示的publicvoida(){System.out.println("卡名:青眼白......
  • 分布式id的方案
    1简介在分布式系统架构中,通常会涉及到分布式全局唯一ID的生成在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。如在金融、电商、支付、等产品......
  • open for java 创建圆弧
    //徐华进2022/12/20///*==================================================================================================Copyright(c)2004UGS......