Script标签是我们常用的引用js脚本的一种方式。

撸代码的时候,我们常常只写src属性,直接忽略其他属性。

最近发现了2个可以利用的属性:async、defer。

顾名思义async就是异步,在不影响其他资源加载的同时,异步加载这个文件;defer就是延迟加载。

下面是高三上的解释:

Async: 可选属性。表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本。只对外部脚本文件有效(写在html文件中的js代码,添加此属性无效,仍按代码加载顺序执行)。
Defer: 可选属性。标识脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。

是否真的如上所述,下面我们用个demo来验证一下。

Html代码:

进入的js文件中,同文件序号分别console.log,1,2,3,4,5,6;

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>test1 test2</h1>
</body>
<script defer>
  console.log(0)
</script>
<script src='js1.js'></script>
<script src='js2.js'></script>
<script src='js3.js'></script>
<script src='js4.js'></script>
<script src='js5.js'></script>
<script src='js6.js'></script>
</html>

在浏览器中打开这个html文件,我们可以看到6个js文件按照顺序加载。

    

Ok.现在我给js1文件加上defer属性,看看。

<script defer src='js1.js'></script>

实验证明:

js文件依然按照书写顺序加载。

但是在控制台可以看到,js1文件的代码是最后执行的

   

那我们还原代码,给js6文件加上async属性试试,看看会不会第一个输出6

<script async src='js6.js'></script>

很遗憾,实时并没有按照预想的那样输出6,0,1,2,3,4,5

如上图代码还是按照顺序执行了,为什么defer生效了,async没生效呢?

我们换个文件试试,给中间位置的某个文件添加async属性。我给js3加了async属性后,代码执行顺序发生了如下变化:

那么问题又来了,为什么不是想象中的那个顺序:3,0,1,2,4,5,6

下面我们来分析一下原因

1,为什么async属性加到最后一个script标签中无效?

2,为什么添加了async属性的代码不是优先执行的?

我们都知道,js是按照书写顺序加载,按照书写顺序执行的。文件加载之后,程序便开始解析文件中的代码。

因此添加了async属性的文件,需要加载到这个文件位置的时候才会生效,js6已经是最后一个文件了,最后一个加载的文件中的代码自然就最后执行,因此看起来async在我们的第一个demo中没有生效。

Async是异步加载,而不是优先加载,因此js3文件添加了async属性后,当文件加载到js3,同时开始加载js3之后的文件,于是便出现了上图0,1,2,4,3,5,6的结果,当然这个结果不是必然的,因为我们的demo里面的代码非常简短,如果js4中的代码逻辑复杂,那么结果可能任然是0,1,2,3,4,5,6。

说到这里,大家明白async和defer的原理了吗?

那么什么场景下可以用到这些属性呢?

比如有些第三方库,要求在header中引入(这就意味着第三方插件库会优先加载),但是我们并不需要在页面加载之初就用到这个插件。那么我们可以加上defer属性使之最后加载。同理,如果页面加载的同时需要用到第三方插件,那么我们引用的时候可以加async属性,这样网站内的资源就可以与插件资源异步加载。这中方法会给网站其他资源的加载节省出一些时间,不失为一种页面优化的方法。

参考资料:

JavaScript高级程序设计(第3版)

script标签中的async、defer属性的更多相关文章

  1. 浅谈script标签中的async和defer

    script标签用于加载脚本与执行脚本,在前端开发中可以说是非常重要的标签了.直接使用script脚本的话,html会按照顺序来加载并执行脚本,在脚本加载&执行的过程中,会阻塞后续的DOM渲染 ...

  2. script标签加载顺序(defer & async)

    script 拥有的属性 async:可选,表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本.只对外部脚本文件有效. charset:可选.表示通过 src 属性指 ...

  3. 关于html中的 script标签中的 代码写法有效性? easyui tabs的href不能载入内容页面

    script标签, 即 html中的 js脚本区域中: 它其实就是一个 普通的 html标签, 在 html 渲染器 parser 看来, 它跟其他任何的普通 的 html标签 , 比如 p 标签, ...

  4. HTML5 script 标签的 crossorigin 和integrity属性的作用

    Bootstrap 4 依赖的基础库中出现了两个新的属性 <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.m ...

  5. script标签中type为"text/x-template"或"text/html"

    写过一点前端的都会碰到需要使用JS字符串拼接HTML元素然后append到页面DOM树上的情况,一般的写法都是使用+号以字符串的形式拼接,如果是短点的还好,如果很长很长的话就会拼接到令人崩溃了. 比如 ...

  6. script标签中type为<script type="text/x-template">是个啥

    写过一点前端的都会碰到需要使用JS字符串拼接HTML元素然后append到页面DOM树上的情况,一般的写法都是使用+号以字符串的形式拼接,如果是短点的还好,如果很长很长的话就会拼接到令人崩溃了. 比如 ...

  7. javaScript中的小细节-script标签中的预解析

    首先介绍预解析,虽然预解析字面意思很好理解,但是却是出坑出的最多的地方,也是bug经常会有的地方,利用好预解析的特性可以解决很多问题,并且提高代码的质量及数量,浏览器在解析代码前会把变量的声明和函数( ...

  8. 为什么不能在 body 标签的前面的 script 标签中定义 JS 全局变量?

    <!DOCTYPE html> <!-- 为什么不能在 body 标签的前面的 script 标签中定义 JS 全局变量? 在全局环境下的代码就是在页面加载阶段从上到下一边加载一边执 ...

  9. script标签中defer和async属性的区别

    这篇文章来源于JS高级程序设计第三版中关于script标签的介绍,结合查阅的资料写下的学习笔记. 向html页面中插入javascript代码的主要方法就是通过script标签.其中包括两种形式,第一 ...

随机推荐

  1. 向量空间模型(Vector Space Model)

    搜索结果排序是搜索引擎最核心的构成部分,很大程度上决定了搜索引擎的质量好坏.虽然搜索引擎在实际结果排序时考虑了上百个相关因子,但最重要的因素还是用户查询与网页内容的相关性.(ps:百度最臭名朝著的“竞 ...

  2. IntelliJ IDEA 简单设置

    1.在idea中添加try/catch的快捷键 ctrl+alt+t 2.主题修改 选择菜单栏“File--settings--apperance--theme”,主题选择Darcula: 3.代码字 ...

  3. 27.Spark中transformation的介绍

    Spark支持两种RDD操作:transformation和action.transformation操作会针对已有的RDD创建一个新的RDD: 而action则主要是对RDD进行最后的操作,比如遍历 ...

  4. MyEclipse开发第一个java程序HelloWorld

    [学习笔记] 用MyEclipse开发第一个java程序: 我们先看看一个具体例子,给你们有个先入为主的感觉. 步骤一:在Eclipse开发工具中我们New一个java项目, 如图2_1 图2_1 步 ...

  5. find程序实现

    一个简单的查找字符串匹配 #include <stdio.h> #include <string.h> #define MAXLINE 1000 int getline(cha ...

  6. Python class and object

    # Python继承 class Person(object): """人""" def __init__(self, name, age) ...

  7. SAS学习笔记10 宏变量

    一个宏变量存放的值保持不变直到被修改(全局变量) 引用时,变量名前加上"&" 宏变量在引用时放在双引号之间会被解读(单引号不会被解读) 用户定义的宏变量,有三种方式: %l ...

  8. (八)Activiti之流程变量和局部流程变量

    一.流程变量 1.1 概念 如果,当流程走到"学生请假"这个任务节点的时候,此时可以用TaskService设置流程变量,变量值包含请假人.请假时间.请假理由等信息,这些信息存在表 ...

  9. (四)Activiti之流程定义部署之ZIP方式和流程定义查询

    一.流程定义部署之ZIP方式 上一章节我们使用classpath的方式加载流程定义文件,这里我们使用ZIP的方式. 1.1 用activiti插件生成bpmn和png图片之后,压缩到一个zip格式的压 ...

  10. 写给Web开发人员看的Nginx介绍

    译者注:不知道其他开发者是否和我一样,参与或者写了很多Web项目,但是却没有真正的去完整的部署应用,很多时候都是交给ops即运维的同学帮忙来做.而作为一个有节操的开发者,我认为了解一些服务器方面的知识 ...