今天群里有人问为什么会出现脚本的加载顺序与定义脚本顺序不一致的问题,这个问题引起了我的好奇,经过一番调研,有了这篇文章。

这是一个伪命题吗?

首先,W3C 推荐 script 脚本应该被立即加载和执行,其次,经过网络搜索,我只发现了 1 例相同的问题,所以这个问题的真伪其实还有待进一步验证,但是从逻辑上说,浏览器会并行加载静态资源,对于 Chrome,可以并行加载 6 个资源,如果其中一个资源获取的比较缓慢,那么会影响串行的下 6 个请求的发送,如果能够预先测试出 6 个通畅的请求,一并发送,那么就可以提升网络加载的整体性能。但浏览器是否有这一层优化呢?目前我只见到这篇文章提到过浏览器似乎有这个优化算法,但是并没有在其他地方得到确认。


标签的价值

我们有两种方式使用 <script> 标签:

  1. 通过设置 src 属性引入外部 JavaScript 静态资源;
  2. 执行 <script> 开闭标签内的 JavaScript 脚本;

但其实本质上这两种方式是一回事,其最终的目的就是让浏览器在当前页面执行 JavaScript 脚本,只不过对于前者而言多了一道工序:将服务器返回的 JavaScript 脚本内容插入 <script> 标签内部,然后在执行它。

因此,对于 <script> 标签,我们唯一关心的只有一点:JavaScript 脚本被执行的时机


标签的加载顺序

在页面中,我们有两处地方可以放置 <script> 标签:

  1. <head> ... </head> head 标签内部;
  2. <body> ... </body> body 标签内部;

<head> 标签中插入引用外部 JavaScript 会导致 <body> 标签内的内容在 JavaScript 被完全下载,解析,执行完毕后才会被解析,这期间用户会看到浏览器一片空白,因此会影响用户体验。(这是由于浏览器从上至下解析 HTML 文档,而 JavaScript 的下载,解析和执行会中止浏览器的解析过程)。

因此业界通行的做法是,将 script 标签放置 <body> 底部,从而避免 JavaScript 阻塞页面渲染。

但无论如何,我们的 JS 脚本的执行顺序是相同的:根据其在页面中的位置决定先后顺序。

但是我们可以通过两个属性改变这一顺序。


script 常用属性:defer 和 async

async 属性

async 属性是 HTML5 规范新推出的一个属性,用来告知浏览器应该尽可能的异步加载脚本。所有的浏览器都支持
该属性。具有该属性的脚本我们既无法得知它下载的时间,也无法得知它执行的时机,我们唯一知道的只有两点:

  1. 脚本会被异步下载;
  2. 脚本下载完毕后会立即执行,此时会阻止 HTML 的渲染;

⚠️ 注意,script 标签必须有 src 属性,且属性值有效。


defer 属性

defer 属性向浏览器指明了脚本被执行的时机:“文档解析之后,DOMContentLoaded 事件被触发之前(即 HTML 文档被完全加载和解析,不管样式表,图片或 iframe 是否加载完毕。恩,一个很微妙的时间

script 加载顺序问题的延展研究的更多相关文章

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

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

  2. DOM加载顺序

    最近一直在困扰dom的加载顺序问题,经常会遇到以为绑定好的事件不响应等情况,一头雾水,直到请教了周围的同事,才发现了解dom的加载顺序是多么的重要. 关于这个问题,其实网上已经有一些介绍,但是我觉得并 ...

  3. 详解web.xml中元素的加载顺序

    一.背景 最近在项目中遇到了启动时出现加载service注解注入失败的问题,后来经过不懈努力发现了是因为web.xml配置文件中的元素加载顺序导致的,那么就抽空研究了以下tomcat在启动时web.x ...

  4. html页面元素加载顺序

    一般来说,添加背景图片有三种办法: 直接写在标签的style里面,如: <div style="background-image:url('images/Css.JPG')" ...

  5. jsp页面中的代码执行加载顺序介绍

    1. java是在服务器端运行的代码,jsp在服务器的servlet里运行,而javascript和html都是在浏览器端运行的代码.所以加载执行顺序是是java>jsp>js. 2. j ...

  6. javascript加载顺序

    javascript加载顺序 <script type="text/javascript" src="jquery.js"></script& ...

  7. (转)JS加载顺序

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

  8. JS 和 CSS 的位置对其他资源加载顺序的影响

    JS 和 CSS 在页面中的位置,会影响其他资源(指 img 等非 js 和 css 资源)的加载顺序,究其原因,有三个值得注意的点: JS 有可能会修改 DOM. 典型的,可能会有 document ...

  9. Ckeditor 的加载顺序

    我们的只用在文件里面引用一个CKEditor的js文件--CKEditor目录下的ckeditor.js文件, 该文件会完成后续的所有的CKEidtor依赖的js文件的加载. 所依赖的js文件加载顺序 ...

随机推荐

  1. PDB、PD、PMP、RTB哪个更好?为品牌主解锁程序化购买的选择技巧

    PDB.PD.PMP.RTB哪个更好?为品牌主解锁程序化购买的选择技巧 https://baijiahao.baidu.com/s?id=1620277114893208111&wfr=spi ...

  2. TCP 123=网络时间协议(NTP),Net Controller

    TCP 123=网络时间协议(NTP),Net Controller

  3. redis 数据迁移

    最近有个项目因为要搬迁服务器的原因,去找了服务器公司的运维,需要收费,于是果断决定自己实现这个功能.现在百度上已经一大把redis数据库迁移的教程,大部分是利用主从复制或者利用redis的RDB备份之 ...

  4. oracle数据迁移到mysql

    今天遇到需求要把oracle的部分数据搬到mysql,用java代码抓数据,然后拼接成sql语句,然后用navicat执行sql脚本的方法,导入数据库. import oracle.jdbc.driv ...

  5. maven package install deploy区别

    package 命令完成了项目编译.单元测试.打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库install 命令完成了项目编译.单元测 ...

  6. css 计算属性 calc的使用

    宽度等于父元素的宽度减去16像素 高度等于父元素的高度减去16像素 注意:100%和16px   与减号之间必须有空格,否则高度会失效!!!! .box{ width:calc(100% - 16px ...

  7. nodejs(四)file System模块 解决Cross device link错误 EXDEV

    var fs = require('fs'); /*cross device link fs.rename('c:\\err.LOG','d:\\err.LOG',function(err){ con ...

  8. hadoop备战:yarn框架的简单介绍(mapreduce2)

    新 Hadoop Yarn 框架原理及运作机制 重构根本的思想是将 JobTracker 两个基本的功能分离成单独的组件,这两个功能是资源管理和任务调度 / 监控.新的资源管理器全局管理全部应用程序计 ...

  9. DeepMind提出空间语言集成模型SLIM,有效编码自然语言的空间关系

    前不久,DeepMind 提出生成查询网络 GQN,具备从 2D 画面到 3D 空间的转换能力.近日.DeepMind 基于 GQN 提出一种新模型.可以捕捉空间关系的语义(如 behind.left ...

  10. 005-redis-命令-无序集合,有序集合

    Redis 无序集合命令 下表列出了 Redis 集合基本命令: 序号 命令及描述 1 SADD key member1 [member2] 向集合添加一个或多个成员 2 SCARD key 获取集合 ...