概述

前几天研究了一个下开发者工具的performance面板,挺有意思的。文件的加载顺序又对页面性能有着至关重要的影响。所以我用performance面板研究了以下几种配置的加载顺序,把过程和结果记录下来,供以后开发时参考,相信对其他人也有用。

  1. js放在body最后的加载。
  2. js放在body前面的加载。
  3. async,defer的加载。
  4. setTimeout的加载。
  5. onload事件的加载。
  6. DOMContentLoaded事件的加载。
  7. onreadystatechange事件的加载。
  8. 加入jquery的加载。

performance面板。

利用开发者工具的performance面板可以查看首屏时间和加载情况。方法是:

  1. 打开chrome开发者工具的performance面板
  2. 点击左上角实心小圆点右边的刷新图标。(快捷键:Ctrl + Shift + E)

js放在body最后

代码如下:

//haha.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="haha.css">
</head>
<body>
<div id="haha"></div>
<script type="text/javascript" src="haha.js"></script>
</body>
</html> //haha.css
div {
width: 800px;
height: 800px;
background-color: green;
font-size: 300px;
} //haha.js
var a = 1;
while(a < 1000000000) {
a++;
}

performance面板部分截图如下:



图一表示一直到2800ms才开始渲染首屏;图二表示css先加载,js后加载,他们是同时加载的,并且虽然js先加载完,但是并没有执行,而是等到css加载完并执行之后再执行的,这也符合了谁写在前面谁先执行的规范。

从第一张图可以得出,js的运行阻塞了首屏的渲染,一直到2800ms才开始渲染首屏。这表示js的运行阻塞了渲染。

从第二张图可以得出,css的下载没有阻塞js的下载,并且谁写在前面谁先执行。

js放在body前面

代码如下:

//haha.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="haha.js"></script>
<link rel="stylesheet" type="text/css" href="haha.css">
</head>
<body>
<div id="haha"></div>
</body>
</html> //haha.css
div {
width: 800px;
height: 800px;
background-color: green;
font-size: 300px;
} //haha.js
var a = 1;
while(a < 1000000000) {
a++;
}

performance面板部分截图如下:



图一表示一直到2800ms才开始渲染首屏;图二表示css先加载,js后加载,他们是同时加载的,并且虽然js先加载完,但是并没有执行,而是等到css加载完并执行之后再执行的,这也符合了谁写在前面谁先执行的规范。

从第一张图可以得出,js的运行阻塞了首屏的渲染,一直到2800ms才开始渲染首屏。这符合我们的预期。

从第二张图可以得出,js的下载并没有阻塞css的下载,当js在下载的时候也会下载css。但为什么css的下载这么慢???因为js在下载完毕之后开始执行,在js执行的时候阻塞了css的下载!所以css的下载暂停了,一直等到js执行完毕之后再继续下载。

所以从上面2个实例可以得出:

  1. js在下载的时候不会阻塞页面的下载和渲染(可能会阻塞渲染?)。
  2. js在执行的时候会阻塞页面的下载和渲染。

另外,css的执行和下载不会阻塞任何事情。还有一点需要注意的是,js在执行的时候可能不会阻塞图片等资源的下载,而且根据浏览器的优化,js在执行的时候究竟会不会阻塞资源下载还是要看浏览器的处理,但是可以肯定的是会阻塞页面的渲染。

那么如何让js不阻塞页面的渲染,提高首屏时间呢?我们继续进行实例。

defer

我们给script标签加上defer。代码如下:

//haha.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script defer type="text/javascript" src="haha.js"></script>
<link rel="stylesheet" type="text/css" href="haha.css">
</head>
<body>
<div id="haha"></div>
</body>
</html> //haha.css
div {
width: 800px;
height: 800px;
background-color: green;
font-size: 300px;
} //haha.js
var a = 1;
while(a < 1000000000) {
a++;
}

performance面板部分截图如下:



从第一张图中可以看出,首屏时间并没有变化。

从第二张图中可以看出,js并没有在加载完成之后立刻运行,而且css下载完成之后都没有运行,而是等到css执行完毕之后才运行。这和js放在body最下面的效果完全一样。

async

我们给script标签加上async。代码如下:

//haha.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script async type="text/javascript" src="haha.js"></script>
<script async type="text/javascript" src="haha2.js"></script>
<link rel="stylesheet" type="text/css" href="haha.css">
</head>
<body>
<div id="haha"></div>
</body>
</html> //haha.css
div {
width: 800px;
height: 800px;
background-color: green;
font-size: 300px;
} //haha.js
var a = 1;
while(a < 1000000000) {
a++;
} //haha2.js
var a = 1;
while(a < 1000000000) {
a++;
}

performance面板部分截图如下:



从第一张图中可以看出,首屏时间并没有变化。

从第二张图中可以看出,虽然haha2.js后加载,但是haha2.js先执行,并且都没有阻塞css的下载和执行,这代表都是在css下载和执行完毕之后才执行的。

setTimeout

我们给haha.js加上setTimeout。代码如下:

//haha.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="haha.css">
</head>
<body>
<div id="haha"></div>
<script type="text/javascript" src="haha.js"></script>
</body>
</html> //haha.css
div {
width: 800px;
height: 800px;
background-color: green;
font-size: 300px;
} //haha.js
setTimeout(function() {
var a = 1;
while(a < 1000000000) {
a++;
}
}, 2000);

performance面板部分截图如下:

可以看到,首屏时间得到极大优化,大约100ms就出现首屏,并且直到2000ms才开始执行js。

所以有很多人利用setTimeout进行延迟加载,延迟几秒后再通过js插入script标签进行加载js。但是这样有一个确定,就是我们精确地确定这个延迟时间。

onload

我们给haha.js加上onload。代码如下:

//haha.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="haha.css">
</head>
<body>
<div id="haha"></div>
<script type="text/javascript" src="haha.js"></script>
</body>
</html> //haha.css
div {
width: 800px;
height: 800px;
background-color: green;
font-size: 300px;
} //haha.js
window.onload = function () {
var a = 1;
while(a < 1000000000) {
a++;
}
}

performance面板部分截图如下:

可以看到,不仅首屏时间得到优化,而且js很早就开始执行了,大约从55ms就开始加载js。

DOMContentLoaded

那给haha.js加上DOMContentLoaded事件呢?。代码如下:

//haha.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="haha.css">
</head>
<body>
<div id="haha"></div>
<script type="text/javascript" src="haha.js"></script>
</body>
</html> //haha.css
div {
width: 800px;
height: 800px;
background-color: green;
font-size: 300px;
} //haha.js
document.addEventListener("DOMContentLoaded", function(event) {
var a = 1;
while(a < 1000000000) {
a++;
}
});

performance面板部分截图如下:

可以看到,虽然在DOMContentLoaded事件之后(大约51.5ms)立即执行js,但是这个时候DOMContentLoaded事件并没有结束,直到js执行完成之后才结束,然后才进行页面渲染。大大延迟了首屏时间。

onreadystatechange

那给haha.js加上onreadystatechange事件呢?。代码如下:

//haha.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="haha.css">
</head>
<body>
<div id="haha"></div>
<script type="text/javascript" src="haha.js"></script>
</body>
</html> //haha.css
div {
width: 800px;
height: 800px;
background-color: green;
font-size: 300px;
} //haha.js
document.onreadystatechange = function () {
if(document.readyState === "complete") {
var a = 1;
while(a < 1000000000) {
a++;
}
}
}

performance面板部分截图如下:

可以看到,首屏时间得到优化,而且在readyState为complete之后(大约48ms)立即执行js,但是这个时候并不能判断DOM是否已经加载完成。

加入jquery

我先引入jquery再引入haha.js。代码如下:

//haha.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="haha.css">
</head>
<body>
<div id="haha"></div>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="haha.js"></script>
</body>
</html> //haha.css
div {
width: 800px;
height: 800px;
background-color: green;
font-size: 300px;
} //haha.js
var a = 1;
while(a < 1000000000) {
a++;
}

performance面板部分截图如下:

可以看到,首屏时间奇迹般的得到了优化。就算我们并没有使用ready方法,但是也得到了优化。可能jquery里面进行了某些优化处理吧。

而且,经过试验,当haha.js里面用DOMContentLoaded事件时,首屏时间也奇迹般的得到了优化。所以我猜测,jquery对DOMContentLoaded事件进行了处理,让他提前结束???

总结

  1. 谁先加载谁先执行,除非async。
  2. defer没卵用。
  3. 有jquery用jquery,没jquery用onload,千万别单独使用DOMContentLoaded。(其中的机制可要好好琢磨了。)

Performance面板看js加载的更多相关文章

  1. Arcgis for js加载百度地图

    看转:https://blog.csdn.net/qq_41046162/article/details/80248281 通过学习了一段时间的arcgis for js,让我来讲一下如何在arcgi ...

  2. FusionCharts简单教程(二)-----使用js加载图像和setDataXML()加载数据

          前面一篇对FusionCharts进行了一个简单的介绍,而且建立了我们第一个图形,但是那个是在HTML中使用<OBJECT>和<EMBED>标记来加载图形的,但是这 ...

  3. (转)JS加载顺序

    原文:http://blog.csdn.net/dannywj1371/article/details/7048076 JS加载顺序 做一名合格的前端开发工程师(12篇)——第一篇 Javascrip ...

  4. 使用js加载图像和setDataXML()加载数据

    使用js加载图像和setDataXML()加载数据 前面一篇对FusionCharts进行了一个简单的介绍,而且建立了我们第一个图形,但是那个是在HTML中使用<OBJECT>和<E ...

  5. 记录一个bootstrap因js加载顺序导致的问题(tstrap-table-mobile.min.js:7 Uncaught TypeError: Cannot read property 'defaults' of undefined)

    问题描述: 网上找了会没看到答案,然后看了下源码,发现也没有问题,想到js加载的顺序,改了下,发现问题没了. 正确的顺序: 我之前把 <script src="/js/plugins/ ...

  6. javascript不依赖JS加载顺序事件对象实现

    背景: 在现在WEB开发中,稍复杂一点的页面,都会涉及到多个模块,尤其是类似seajs.LABjs.requireJS等模块工具出来后,前端开发者分模块开发已经慢慢变成一种习惯了,但是多个模块间的常常 ...

  7. (转) Arcgis for js加载百度地图

    http://blog.csdn.net/gisshixisheng/article/details/44853709 概述: 在前面的文章里提到了Arcgis for js加载天地图,在本节,继续讲 ...

  8. 组件推荐Forloop.HtmlHelpers 用来实现MVC的js加载顺序

    最近在开发的时候遇到js加载顺序的问题,layui在底部声明了js,但是我想在页面其他地方使用分布视图,分布视图内有自己的js逻辑,发现不能执行,一看就发现,这里的js应该加在layui后面执行才能有 ...

  9. 初踩坑JS加载与audio接口:点击头像开始/暂停背景音乐

    背景 封楼期间难得空闲,也静不下心学习,空闲之余萌生了重做引导单页的想法.因为之前都是扒站(某大公司游戏官网)+小改,一来虽然很炫酷,但本人水平有限,仍有很大一部分JS无从下手,甚至是看不懂|-_-| ...

随机推荐

  1. BP神经网络与Python实现

    人工神经网络是一种经典的机器学习模型,随着深度学习的发展神经网络模型日益完善. 联想大家熟悉的回归问题, 神经网络模型实际上是根据训练样本创造出一个多维输入多维输出的函数, 并使用该函数进行预测, 网 ...

  2. Mybaits

    1.Mybatis全注解形式  (在注解上不能直接使用动态Sql,必须要在前后面加上<script>SQL</script>标签,否则会报错): @Select("& ...

  3. python,opencv,imread,imwrite,存储,读取图像像素不一致,这种情况是label使用jpg格式

    最近在做图像分割,需要使用一些分割图片的label,但是发现存储的分割label感觉被平滑过了,即使使用 image = cv2.imread(info['path'],cv2.IMREAD_UNCH ...

  4. 史上最坑 idea 更改代码不生效

    原来, 如果本地多次调整过系统时间,那么gradle 的缓存 会缓存 你的 上次编译时间再未来,那么你再怎么编译,都很难生效,即使删除了生成的字节码目录. 然后invalidate caches/re ...

  5. 2018面向对象程序设计(Java)第17周学习指导及要求

    2018面向对象程序设计(Java)第17周学习指导及要求(2018.12.20-2018.12.23)   学习目标 (1) 掌握线程同步的概念及实现技术: (2) Java线程综合编程练习 学习资 ...

  6. linux网络日志分析

    1.清空日志的技巧 2.访问日志格式分析 3. web日志统计举例

  7. springboot 整合 mybatis

    spirngboot 整合mybatis有两种方式 第一种 无配置文件注解版,这一种符合springboot的风格 第二种 有配置文件xml版本,这一种就是传统的模式 无论哪一种,首先都需要加入MyS ...

  8. 【Django】django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.

    最近学习Django的过程中,在cmd打算使用python manage.py shell来测试数据的时候,当我一导入自己写的model类,就发现报了这个错误django.core.exception ...

  9. c++ 面试题(数据库)

    1,索引的原理: https://www.cnblogs.com/songwenjie/p/9414960.html https://blog.csdn.net/qq_32924343/article ...

  10. 445. Add Two Numbers II 链表中的数字求和

    [抄题]: You are given two non-empty linked lists representing two non-negative integers. The most sign ...