我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

对于一个网页来说,css是放在顶部head区域加载的,而js是放在页脚body的最下方加载的,这个是根据它们的特性所决定的。对于苏南大叔的页面来说,一个页面里面不会有很多个js或者css文件,它们都被使用grunt合并成了一个文件。然后,css放顶部,js放底部,进行加载。所以理论上来说,并不会阻碍页面的加载,也不会影响页面加载线程。但是,普通的页面呢?

苏南大叔:网页控制script脚本异步执行方案,理解script标签defer属性 - script-defer
网页控制script脚本异步执行方案,理解script标签defer属性(图3-1)

大家好,这里是苏南大叔的“程序如此灵动”博客,这里讲述苏南大叔和计算机代码的故事。本文讲述script标签的defer属性,本质上来说,defer是用来异步加载的。那么,它的使用方式是怎么样的呢?
本文测试环境:win10chrome@100.0.4896.60

基本说明

defer的意思是延迟(Deferred),并不是异步,虽然看起来效果确实是异步,但是其本意仅仅是延迟执行。给js脚本添加 defer属性,这个属性会让脚本的加载与文档的解析同步解析,然后在文档解析完成后再执行这个脚本文件,这样的话就能使页面的渲染不被阻塞。

在 HTML4.01 规范中规定:
设置后,这个布尔属性会向用户代理提示该脚本将不会生成任何网页内容(例如,JavaScript中不会生成 “document.write”),因此,用户代理可以继续解析和渲染。

测试代码

这里的测试代码,加上了type="module"es6 module情况,有关说明文章见这里:

测试方式是通过浏览器访问web,并不是双击.html文件。

这里测试以下几种代码:

<script type="module" src="./1.js"></script>
<script type="module" defer src="./2.js"></script>
<script type="module">
import aa from './3.js'
</script>
<script type="module" defer>
import aa from './4.js'
</script>
<script defer src="./5.js"></script>
<script src="./6.js"></script>
<script defer>
console.log("7.js");
</script>
<script>
console.log("8.js");
</script>

其中3.js4.jsexport了一个空函数。

console.log("3.js");
export default ()=>{};

测试结果

这里先说基本原则:

  • defer的意思是异步执行,被设置defer的代码,在效果上会等待文档加载完毕后再执行,忽视其在页面中的物理位置。
  • type="module"script,直接默认就是defer的。加不加defer都是defer
  • 内联的script(就是把逻辑写在html页面里面的,不是保存为一个文件的),默认都不是defer的。加不加defer都不是defer

然后苏南大叔在所有的被测试js前面,再加个内联的onload

<script>
    window.addEventListener('DOMContentLoaded', function () {
      console.log('DOMContentLoaded')
    })
</script>

然后,这8种js,以及这个DOMContentLoaded,到底谁先谁后呢?答案见下图:

苏南大叔:网页控制script脚本异步执行方案,理解script标签defer属性 - 执行顺序
网页控制script脚本异步执行方案,理解script标签defer属性(图3-2)

结论是:先执行不defer的,再执行defer,最后执行DOMContentLoaded

特殊情况

在设置了defer.js里面,使用document.write语句的话。会得到警告信息,并且不会正确输出.write信息。

Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

苏南大叔:网页控制script脚本异步执行方案,理解script标签defer属性 - 不支持write
网页控制script脚本异步执行方案,理解script标签defer属性(图3-3)

参考文献

综述

本文讲述了scriptdefer属性,它可以把一些js移动到后面执行,以免阻碍页面渲染。更多js文章,可以点击:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   js    h5