浅析我对JS延迟异步脚本的思考

关于对延迟脚本的思考

asyncdefer属性的脚本,相信大家都听说过,但是他的真正执行细节是什么样子的?很少有文章认真研究它,可能不太有人注重细节,但其实真正有技术含量的工作和项目,对于性能要求极高,那么细节就很重要了.需要不断的实验自我尝试

最近几个月,我一直在研究一些技术,例如linux,操作系统,算法等,预计要持续学习到今年年底。红宝书第四版出来后,我也是花了很多时间去看。对于延迟脚本,自己也是做了一个实验,写下了这篇总结

什么是延迟脚本?

script标签,带async和defer属性等,通过document.createElement('script')创建并且没有指定script.async=false的脚本默认为异步延迟脚本(必须为非内联脚本),如下所示:

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
</head>

<body>

</body>
<script src="./async1.js" async></script>
<script src="./async2.js" async></script>
<script src="./defer1.js" defer></script>
<script src="./defer2.js" defer></script>
<script src="./common1.js"></script>
<script src="./common2.js"></script>
<script src="./common3.js"></script>

</html>

以上7个脚本文件,其中common开头为非异步延迟脚本,其余的都指定了延迟脚本的模式,分为async和defer两种

通过document.createElement创建的标签插入默认为async模式

开始实验

我一共写了2个async和2个defer标签,其它的都是普通标签.其中async1.js里面有4000行代码,其它都是一个console.log而已

第一次实验结果:

再次刷新页面(注意我已经禁用了浏览器缓存),结果为:

再次刷新,发现async执行时机和顺序不确定,但是能确定defer肯定在async之后执行。

原因在于:async是告诉浏览器,可以不必等到它下载解析完后再加载页面,也不用等它执行完后再执行其他脚本,俗称异步执行脚本

看下载执行时机和打印结果的对比

打印结果:

对应的下载执行时机

从上面看,下载时机async和普通模式都是同样并行下载,只有defer是最后才下载(http1.1有并发数量限制,可是这里并不是并发限制,当我删除common的引用后,我发现defer永远都是最后下载的)

asyncdefer两种模式,区别在于:

  • async是告诉浏览器,它不会操作dom,可以不必等到它下载解析完后再加载页面,也不用等它执行完后再执行其他脚本,俗称异步执行脚本, 多个async无法保证他们的执行顺序,例如async1和async2无法按顺序执行
  • defer是在解析到结束到</html>标签后才会执行,俗称推迟执行脚本,多个defer可以按顺序执行,例如defer1和defer2可以按顺序执行(实际上也不保证顺序执行)
  • 解析到script标签后,async是直接下载
  • 解析到script标签后,defer是最后下载

相同点:

  • 多个async或者defer标签实际上都不能保证顺序执行
  • 都不会阻塞解析其他script标签内容的解析和页面渲染
  • 他们都会在浏览器load事件前执行,但是不保证是在DomContentLoad事件前还是后执行

影响多个异步脚本的执行顺序因素

  • 脚本文件大小
  • 网络传输因素

特殊情况

当所有的脚本文件都很小很小的时候,结果会在很大概率稳定在

使用的注意点

  • 异步推迟脚本的执行顺序并不稳定,所有尽量只有一个
  • 使用异步推迟脚本时,应该考虑什么场景才使用,而不是滥用它

写在最后

到此这篇关于浅析我对JS延迟异步脚本的思考的文章就介绍到这了,更多相关JS 延迟异步脚本内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JS同步、异步、延迟加载的方法

    本文讲述了JS同步.异步.延迟加载的方法.分享给大家供大家参考,具体如下: 一:同步加载 我们平时使用的最多的一种方式. <script src="http://yourdomain.com/script.js"></script> 同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当当前加载完成,才能进行下一步操作.所以默认同步执行才是安全的.但这样如果js中有输出document内容.修改dom.重定向等行为,就会造成页面堵塞.所以一般建议

  • 浅谈原生JS中的延迟脚本和异步脚本

    一.延迟脚本 defer HTML4.0中为<script> 标签添加了个defer属性.属性的用途是表民脚本在执行时不会影响页面的构造. 脚本会被延迟到页面加载完毕的时候,执行.也就是当浏览器解析到</html> 标签后才会执行代码.在HTML5规范中,defer属性中适用于外部脚本. 而家了defer  的脚本文件会比DOMContentLoaded事件触发前执行. 二.异步脚本 async HTML5为<script>添加了个async属性.这个属性与defer属

  • 浅析我对JS延迟异步脚本的思考

    关于对延迟脚本的思考 async和defer属性的脚本,相信大家都听说过,但是他的真正执行细节是什么样子的?很少有文章认真研究它,可能不太有人注重细节,但其实真正有技术含量的工作和项目,对于性能要求极高,那么细节就很重要了.需要不断的实验自我尝试 最近几个月,我一直在研究一些技术,例如linux,操作系统,算法等,预计要持续学习到今年年底.红宝书第四版出来后,我也是花了很多时间去看.对于延迟脚本,自己也是做了一个实验,写下了这篇总结 什么是延迟脚本? script标签,带async和defer属

  • 跟我学习javascript的异步脚本加载

    先来看这行代码: <script src = "allMyClientSideCode.js"></script> 这有点儿--不怎么样."这该放在哪儿?"开发人员会奇怪,"靠上点,放到<head>标签里?还是靠下点,放到<body>标签里?"这两种做法都会让富脚本站点的下场很凄惨.<head>标签里的大脚本会滞压所有页面渲染工作,使得用户在脚本加载完毕之前一直处于"白屏死机&

  • javascript带回调函数的异步脚本载入方法实例分析

    本文实例讲述了javascript带回调函数的异步脚本载入方法.分享给大家供大家参考.具体实现方法如下: var Loader = function () { } Loader.prototype = { require: function (scripts, callback) { this.loadCount = 0; this.totalRequired = scripts.length; this.callback = callback; for (var i = 0; i < scri

  • 原生JS发送异步数据请求

    在做项目的时候,有时候需要用到异步数据请求,但是如果这个时候没有框架的依赖,就需要用到原生JS进行异步数据请求.这时候无非有两种请求方式,一种是AJAX,另一个是JSONP.通过原生JS对异步请求进行简单的封装. AJAX AJAX是一种数据请求方式,不需要刷新整个页面就能够更新局部页面的数据.AJAX的技术核心是XMLHttpRequest对象,主要请求过程如下: 创建XMLHttpRequest对象(new) 连接服务器(open) 发送请求(send) 接收响应数据(onreadystat

  • 浅谈js的异步执行

    1.Javascript语言的执行环境是"单线程"(single thread): 优点:实现起来比较简单,执行环境相对单纯: 缺点:只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行.常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行. 为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous). 2.&

  • promise和co搭配生成器函数方式解决js代码异步流程的比较

    在es6中引入的原生Promise为js的异步回调问题带来了一个新的解决方式,而TJ大神写的co模块搭配Generator函数的同步写法,更是将js的异步回调带了更优雅的写法. 今天我想对比一下这两种方式,来看看这两种方式的区别以及优劣. 我们先抽象几个操作: 以做饭为例,我们先去买菜,回来洗菜,刷碗,烧菜,最后才是吃.定义如下方法: var buy = function (){}; //买菜,需要3s var clean = function(){}; //洗菜,需要1s var wash =

  • JS动态插入脚本和插入引用外部链接脚本的方法

    在日常开发中,经常遇到 js 动态插入脚本 . 什么是 js 动态插入脚本 ? 指的是在页面加载时不存在,但将来的某一时刻通过修改该 DOM 动态添加的脚本.和操作 HTML 元素一样. js 动态插入脚本也有两种方式:插入 JavaScript 代码和插入外部文件. 一.直接插入 javascript 代码 <script type="text/javascript"> function sayHi() { alert("hi"); } </sc

  • JS ES6异步解决方案

    最初使用回调函数 ​ 由于最初j s官方没有明确的规范,各种第三方库中封装的异步函数中传的回调函数中的参数没有明确的规范, 没有明确各个参数的意义, 不便于使用. ​ 但是node中有明确的规范 ​ node中的的回调模式: 1. 所有回调函数必须有两个参数,第一个参数表示错误,第二个参数表示结果 2. 所有回调函数必须作为函数最后的参数 3. 所有回调函数不能作为属性出现 es6 异步处理模型 Es6 出现以后, 官方就提出了异步处理的规范, 提出了一种适用于所有异步场景的处理模型.该模型有:

  • js fetch异步请求使用实例详解

    目录 认识异步 fetch(url) response.json() 结合async和await 异常处理 post请求 总结 认识异步 首先我们得明白请求是一个异步的过程. 因为请求需要时间向服务器发送请求和接收请求结果. 我们得要等待请求完成然后执行请求完成后的回调,来对接收到的请求结果做处理. fetch(url) 为了方便学习,我们借用一下uni-app教程的api接口. const url = 'https://unidemo.dcloud.net.cn/api/news' 我们需要知

随机推荐