js、css的阻塞问题

  这篇文章主要是探索js、css的加载顺序及其影响问题。

  下面的代码可以让浏览器阻塞:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>阻塞代码</title>
</head>
<body><script>// 阻塞代码,参数单位s
    function blocking(blockingTime) {function getTime() {return new Date().getTime();}var startTime = getTime();// getTime()得到的时间单位是ms,所以乘1000while (getTime() < startTime + blockingTime*1000);}blocking(5);</script><h3>hello</h3>
</body>
</html>

测试一:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>JS/css</title><script>var start = +new Date;</script><script>var end = +new Date;console.log(end-start);</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet">
</head>  <body>
</body></html>

注:其中的+为单目运算符,可以将对象转化为数字。

显然,在控制台输出的结果为0。因为上面的js语句刚刚执行完,就执行下面的语句,所以时间间隔几乎为0。

测试二:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>JS/css</title><script>var start = +new Date;</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet"><script>var end = +new Date;console.log(end-start);</script>
</head>  <body>
</body></html>

这个测试中,我将css置于两个script之间,最后的输出结果为2870, 当然这个值是个随机数,一定是远远大于0的。

然后我们在打开开发者工具的Network的情况下点击刷新,这时再看console控制台打印出的值为2967, 然后我们观察加载css所需的时间:

2.97s,也就是2967ms。

结论: 外部样式的加载会阻塞在它之后的<script>语句的加载,并且<script>是在<link>完全加载结束之后执行的。

  

 

测试3:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JS/CSS</title><script>var start = +new Date;</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet"><script>var endAfterCss = +new Date;console.log("css", (endAfterCss - start));</script></head>
<body><script src="http://udacity-crp.herokuapp.com/time.js?rtt=1&a"></script><div id="result"></div><script>var endAfterScript = +new Date;console.log("js",(endAfterScript - start));</script></body>
</html>

在console控制台的输出如下:

我们可以看到在两者之间还有一个外部的script标签,为什么两者的执行却是几乎同时发生的呢?

  我们同样在network中刷新,然后得到的console控制台信息如下:

    然后查看network,并查看外部css的详情, 如下所示:

 可以看出,css的加载时间就是3.12s,然后它的加载阻塞了下面的script的执行,css一旦加载完毕,下面的script立即执行,所以得到了3118这个值。这个很容易理解。

 注意观察上图,可以发现外部css和外部js的加载时间几乎是同时的,也就是说外部css的加载不会影响到下面的js的加载。

但是为什么在外部js文件下面的js却是3130呢? 外部的script的加载不是也需要一定的时间吗?我们看看js的加载时间。

我们可以看到,外部js的加载时间仅为1.38s,也就是说在外部css还没有加载完的时候js就加载结束了,但是它并没有执行,而是等到css加载完了之后才执行的。所以才会得到3130这个数值。其中的差值就是js执行的时间。

结论: 在css加载的过程中,下面的外部js同时也会加载,只是下面的外部js必须等到上面的css加载完成之后才能执行。 并且js会阻断下面的js的执行,因为js的执行是单线程的,所以在外部css执行结束之后,下面的内联css才会继续执行。

测试4:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JS/CSS</title><script>var start = +new Date;</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet"><link rel="stylesheet" href="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/mancard/css/card_min_dee38e45.css"><script>var endAfterCss = +new Date;console.log("css", (endAfterCss - start));</script></head>
<body><script src="http://udacity-crp.herokuapp.com/time.js?rtt=1&a"></script><div id="result"></div><script>var endAfterScript = +new Date;console.log("js",(endAfterScript - start));</script></body>
</html>

network如下:

即页面中的两个css是同时加载的,并且js也是,即两个css和js都是同时加载的,我的第二个css在html中是在js上面的,但是这里显示js却是先加载的,也就是说第一个css加载的时候,后面的js和css是同时加载的,至于谁最先加载,就不好说了,看下图,在代码没有改变的情况下,js是最后加载的。

说明:黄色部分为 Initial Connection ,即初始链接网络所消耗的时间,这种情况的发生往往是因为多个请求导致的

如果我将耗时较长的css删除,那么我们得到的瀑布流如下所示:

可以看到这里确是js先加载的!

console控制台输出的结果是:

所以说link的加载不会影响js的加载是完全正确的。

结论:  如果同时具有两个link,一个外部的css,那么此三者是同时加载的,只是无法确定后面两者的先后关系。同样的,必须要在css加载结束之后js才能执行。

    如果只有一个css、一个js,那么两者的加载顺序是不确定的。

测试5:

  异步加载js

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JS Bin</title><script>var start = +new Date;</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet"></head><body>test<script src="http://udacity-crp.herokuapp.com/time.js?rtt=1&a" async></script><div id="result"></div><script>var end = +new Date;console.log(end - start);</script></body>
</html>

  表现如下:

  可以看出,css的加载时间为2.37s, 在控制台的输出时间为2368ms,也就是说在css执行完成之后,外部js并没有阻碍下面的内联js的执行,而在页面中我们可以看到2094.6450000,这是指外联js执行的时间,我们在console控制台中可以看到外联js的执行时间为2.07s,也就是说在外联js加载完成之后就立即执行了,而没有等待外联css加载完毕再执行。

  说明:再外联js的代码中我们使用了window.performance.now()方法,这个方法返回的是页面开启后的时间,且其单位为ms, 小数点之后保留了13位,这样的好处是较之于Data.now()更有利于我们检测性能。

  更多关于window.performance.now()的内容可以参照这篇文章:http://www.cnblogs.com/xiaohuochai/archive/2017/03/09/6523397.html

结论: 使用了async属性之后,就可以实现js的异步加载,即该文件的执行不必等待外联css文件加载完成就可以执行,并且也不会阻塞后面的js的加载。

测试6:

  创建<script>元素实现加载外部js

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JS Bin</title><script>var start = +new Date;</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet"></head><body>test<script> var script = document.createElement('script');script.src = "http://udacity-crp.herokuapp.com/time.js?rtt=1&a";document.getElementsByTagName('head')[0].appendChild(script);</script><div id="result"></div><script>var end = +new Date;document.getElementById("result").innerHTML = end-start;</script></body>
</html>

  我们可以看到瀑布流如下所示:

  也就是说,在这种情况下,只有css完全加载完成之后,js才会加载。

结论:  在script标签是动态创建的情况下,其加载的优先级较低,会在css完全加载之后再加载。 注意观察: js的优先级为Low,所以会在css完全加载结束之后加载。

因为动态创建标签也是js语句,之前降到了语句的执行会被css阻塞。

测试7:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JS Bin</title><script>var start = +new Date;</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet"><script>var end0 = +new Date;console.log(end0 - start);</script></head><body><script src="http://udacity-crp.herokuapp.com/time.js?rtt=1&a"></script><div id="result"></div><script>var end1 = +new Date;console.log(end1 - start);</script><script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script><script>var end2 = +new Date;console.log(end2 - start);</script></body>
</html>

输出如下所示:

瀑布流如下所示:

可以看出css加载的过程中,后面的两个js同时加载,且加载的速度比css要快,这时css阻塞着后面的加载,一旦css加载完毕,已经加载好的js立即执行。

参考文章:http://www.cnblogs.com/shinnyChen/p/3762704.html

js、css的阻塞问题相关推荐

  1. 【Web技术】1005- 关于 JS 与 CSS 是否阻塞 DOM 的渲染和解析

    最近系统梳理HTML5所有涉及到的标签时,梳理至<link>和<script>标签时,碰巧想到一个困扰很久的问题,即一般把<script>放在<body> ...

  2. 关于js css html加载顺序整理

    参考原文 豆豆蛙:关于js css html加载顺序整理 1.js放在head中会立即执行,阻塞后续的资源下载与执行.因为js有可能会修改dom,如果不阻塞后续的资源下载,dom的操作顺序不可控. 正 ...

  3. JS / CSS / 网络部分知识总结

    (1)垂直两栏左边固定 右边自适应 //基本布局*{margin: 0;padding: 0;}.outer{height: 200px;}.left{background-color: gold;h ...

  4. js 判断js,css是否引入,确保不重复引入

    js 判断js,css是否引入,确保不重复引入 (2009-10-31 21:33:44) 转载▼ 标签: 杂谈 分类: js 基本原理: function loadjscssfile(filenam ...

  5. JS+CSS控制左右切换鼠标可控的无缝图片滚动代码

    代码简介: 以前见过这种效果,但是是基于FLASH技术,现在是纯用JS实现的,代码有点多,不过效果还不错,实际上它也是一个图片滚动,只不过它完全是用鼠标点击控制的,也就是说鼠标不点击的时候它是静止的, ...

  6. JS+CSS打造一款漂亮绿色相册代码

    代码简介: JavaScript+CSS完成的漂亮相册展示效果,运用了大量CSS代码,JS代码并不多,它可以自动获取链接图片的地址以及TITLE标签的信息,当鼠标点击小图的时候它就会自动加载大图,类似 ...

  7. Django 无法加载静态文件(js,css,image)解决办法

    Django 无法加载静态文件(js,css,image)解决办法 按照这个配置成功: https://jingyan.baidu.com/article/8cdccae92ffc16315413cd ...

  8. golang打包HTML为Android,使用Go开发Web服务,并打包html/js/css等静态资源文件

    Go的高性能,使它天生适合开发io方面的服务,Web服务当然不再话下.同时,Go编译后生成的单文件不是字节码,而是对应平台的机器码,因此它效率更高.资源占用更低. 为了更好的进程程序管理,移动程序时更 ...

  9. gulp实现打包js/css/img/html文件,并对js/css/img文件加上版本号

    参考打包教程: http://www.cnblogs.com/tugenhua0707/p/4069769.html http://www.cnblogs.com/tugenhua0707/p/498 ...

最新文章

  1. mysql spool csv报错_参数化之利用CSV Data Set Config从文件读取参数并关联变量
  2. jQuery控制tab标签页
  3. JNDI的XML相关配置(context.xml和web.xml)
  4. 软件开发如同木匠做桌子
  5. 京东极速版如何取消订单 京东极速版怎样取消订单
  6. linux桌面隐藏鼠标,如何隐藏鼠标光标
  7. adb devices 找不到夜神模拟器解决方法
  8. C#多线程之线程池篇1
  9. 深度学习中所有的优化器的详细介绍与列表化对比分析
  10. 史密斯圆图串并联口诀_史密斯圆图基本原理及应用.ppt
  11. c语言线性表-顺序表(完整版)
  12. FOXIT PDF SDK 8.1 ALL Crack
  13. pgp各种弱类型绕过
  14. 【奋斗人生】心得日记(20191112至20191230)
  15. 【维修】【硬件】【苹果】wifi芯片被加密
  16. Vim统计中文字数和英文单词数(附针对LaTeX的特殊处理)
  17. python 调用百度api 文字转语音
  18. 使用HttpParser类解析网页
  19. 解决新建springboot项目时包导不进来的问题sun.security.provider.certpath.SunCertPathBuilderException: unable to f,已解决
  20. 【华展云】2017年5月第一周官方公告

热门文章

  1. java8-06-自定义Collector-JoinCollector
  2. 搭建前端私有npm杂记
  3. php之常用字符串方法
  4. Python基础语法06--文件
  5. CDH的几个包的下载地址
  6. 举例分析Linux动态库和静态库
  7. C#的加密解密算法,包括Silverlight的MD5算法
  8. 客户资产管理(Custom Asset Management)
  9. IPv6 — 网际协议第 6 版
  10. 4G EPS 中的无线资源类型