异步加载

先看一张整体的异步加载对渲染的阻塞情况图,图片如下:

从这张图里我们可以看到如下4点:

  • 默认情况HTML解析,然后加载JS,此时HTML解析中断,然后执行JS,最后JS执行完成恢复HTML解析
  • defer情况下HTML和JS并驾齐驱,最后才执行JS
  • async情况则HTML和JS并驾齐驱,JS的执行可能在HTML解析之前就已经完成了
  • 最后module情况和defer的情况类似,只不过会在提取的过程中加载多个JS文件罢了

然后我们再来看一下这几种加载JS的情形与DOM事件、onload事件的关系:

从上面的图片我们可以看到如下几点:

  • async 会在加载完JS后立即执行,最迟也会在load事件前执行完。
  • defer会在HTML解析完成后执行,最迟也会在DOMContentLoaded事件前执行完。

从上面我们可以看出,如果你的脚本依赖于DOM构建完成是否完成,则可以使用defer;如果无需DOM的构建,那就可以放心的使用async了。

defer

defer属性仅适用于外部脚本,也就是仅当存在src属性时才会生效;如果一个script标签上面即存在defer属性,也存在async属性,那么浏览器会如何解析这种情况呢?我们通过一段代码验证结果,详情点击这里

也就是说defer的优先级没有async高,我们看一下规范是怎么处理这种情况的。

The defer attribute may be specified even if the async attribute is specified, to cause legacy Web browsers that only support defer (and not async) to fall back to the defer behavior instead of the blocking behavior that is the default.

规范只是说明了在不支持async的情况下浏览器将会回退支持defer,但并没有明确指明两种都支持的这种情况,也就是说这一种情况浏览器自行处理,经过测试,各个浏览器表现行为:

  • Chrome浏览器表现为解析为async特性
  • Safari浏览器表现为async特性
  • Opera浏览器表现为async特性
  • Firefox浏览器表现为async特性

IE暂时没有安装,看来各大浏览器表现一致,总之async的优先级是最高的。

defer兼容性

下面来看看defer的兼容性,移动端一片大绿,可以放心使用,IE10以上可以放心使用,IE6-9有一点小问题就是不会按照script标签的执行顺序进行执行,对于不依赖前后脚本库的可以不用担心,但是如果依赖库的就不行了,比如你的项目依赖jQuery,后面紧接着使用jQuery的方法可能就会出现问题。

asyc

和defer一样,也仅仅适用于外部脚本,也就是仅当存在src属性时才会生效。

async兼容性

async的兼容性在移动端也是一片大绿,IE仅支持IE10+。

module

在现代浏览器中,我们可以声明acript标签type=’module’属性从而拥抱es6的模块导入导出语法,就像这样:

1 <script type="module">
2 import { Max } from "./math.js";
3 console.log(Max(1, 2, 7, 2, 0)); //7
4 </script>

看起来是不是令人很激动,似乎对于开发者十分友好,但是这里也有几个与传统脚本不一样的地方:

  • module默认使用了”use strict”模式,这也意味着不能使用诸如arguments.callee这一类的语法。
  • 模块只会加载一次,无论前后你写了多少次
  • 不支持<!–const a = 1–>注释。
  • module有自己的词法作用域,比如定义一个 var a = 1,并不会创建一个全局变量,因此你并不能通过window.a 访问到它的值

模块的导入方式目前仅支持以下几种模式:

1 支持
2 import {math} from './math.mjs';
3 import {math} from '../math.mjs';
4 import {math} from '/modules/math.mjs';
5 import {math} from 'https://simple.example/modules/math.mjs';
6 //不支持
7 import {math} from 'jquery';

当然,浏览器厂商也在考虑支持 import {math} from ‘jquery’ 这种格式,不过,还是需要一段很长的路要走。

module的默认情况就是defer的,因此不必再module上面又添加一个defer熟悉,并且本身就不支持这种写法,但是支持async属性,其加载渲染方式和async差不多,这里不再赘述。

module兼容性

在移动端的兼容性还算可以,但是IE貌似都败下阵来,只要edge16+以上还算支持,对于不支持module的浏览器可以使用nomodule属性作为版本回退的方案解决。

最后来说一下module的使用建议,大型项目(100模块以上)不建议直接使用模块语法,应该使用打包工具诸如Webpack,Rollup,、或 Parcel,因为静态导入或导出语法是静态可分析的,通过捆绑工具可以去掉多余的模块,我们考虑下面这一种场景:
1 import { Modal } from './util.js';
2 Modal({
3 title: 'hello'
4 })
如果我们通过打包工具打包这一份代码,最终生成的JS文件将会只包含Modal这一个函数,倘若我们没有使用打包工具,浏览器将会下载整个util这一个JS文件,并通过进一步分析了解了使用了Modal这一个函数,这对于没有用到util里面的全部函数的方式,则是一种多余的带宽浪费。
 

JS的异步加载的更多相关文章

  1. js的异步加载你真的懂吗

    面试高频之js的异步加载 讲这个问题之前, 我们从另一个面试高频问题来切入, 我们的web页面从开始解析到页面渲染完成都经历了什么 ?  1  ,  创建document对象, 开始解析页面,    ...

  2. Vue中结合Flask与Node.JS的异步加载功能实现文章的分页效果

    你好!欢迎阅读我的博文,你可以跳转到我的个人博客网站,会有更好的排版效果和功能. 此外,本篇博文为本人Pushy原创,如需转载请注明出处:http://blog.pushy.site/posts/15 ...

  3. js滚动异步加载数据的思路

    <body> <div style="width:200px; height:1000px; border:1px solid red;" id="to ...

  4. JS异步加载的三种方案

    js加载的缺点:加载工具方法没必要阻塞文档,个别js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作. 有些工具方法需要按需加载,用到再加载,不用不加载. 一.def ...

  5. 异步加载的JS如何在chrome浏览器断点调试?

    我们常常利用chrome强大的控制台Sources下面进行代码断点调试,但是通过$.getScript等异步加载JS的方式在Sources里面就是找不到,那如何进行debug断点调试呢? 方案一: 在 ...

  6. 不得不说的JavaScript异步加载

    同步加载的问题 默认的js是同步加载的,这里的“加载”可以理解成是解析.执行,而不是“下载”,在最新版本的浏览器中,浏览器对于代码请求的资源都是瀑布式的加载,而不是阻塞式的,但是js的执行总是阻塞的. ...

  7. javascript 同步加载与异步加载

    HTML 4.01 的script属性 charset: 可选.指定src引入代码的字符集,大多数浏览器忽略该值. defer: boolean, 可选.延迟脚本执行,相当于将script标签放入页面 ...

  8. Highcharts 异步加载数据曲线图表

    导入 data.js 文件 异步加载数据需要引入以下js 文件: <script src="http://code.highcharts.com/modules/data.js&quo ...

  9. Javascript 文件的同步加载与异步加载

    HTML 4.01 的script属性 charset: 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer: boolean, 可选.延迟脚本执行,相当于将script标签放入页面b ...

  10. Highcharts 基本曲线图;Highcharts 带有数据标签曲线图表;Highcharts 异步加载数据曲线图表

    Highcharts 基本曲线图 实例 文件名:highcharts_line_basic.htm <html> <head> <meta charset="U ...

随机推荐

  1. Jenkins设置定时触发器执行任务

    1. 选中任务,选择配置/构建触发器,选择定时构建 2. 填写定时器参数,格式说明如下,共五个参数,参数之间空格隔开,不需要填的直接*号即可.  此处d定时任务的格式遵循 cron 的语法(可以与 c ...

  2. 【LGR-065】洛谷11月月赛 III Div.1

    T1,T2,T3,T4 T1 基础博弈练习题 分析 首先区间长度为1的情况特判,偶数必胜,奇数必败 考虑倒推,如果最后一个位置为偶数那么该位置为必败局面,否则为必胜局面 因为先手到这个位置要减去1就会 ...

  3. OpenHarmony轻量系统中内核资源主要管理方式

    一.背景 OpenAtom OpenHarmony(以下简称"OpenHarmony")轻量系统面向MCU类处理器例如ARM Cortex-M.RISC-V 32位的设备,硬件资源 ...

  4. Python - 字典2

    Python - 访问字典项 您可以通过在方括号内引用其键名来访问字典的项: 示例,获取 "model" 键的值: thisdict = { "brand": ...

  5. HDD成都站·暨HMS Core 6.0产品交流会报名开启

    HUAWEI Developer Day(以下简称HDD)如期而至,将在9月10日和盟友们相聚成都,开启一场属于开发者的交流盛会.本次沙龙活动由上.下半场组成,诚挚地邀请各位开发者参加. 精彩预告 0 ...

  6. 如何在报表中绘制 SVG 统计图

    SVG 作为一种矢量图形,具有任意缩放不失真.可被高质量打印.文件较小.交互性强等优势,正逐渐成为一种主流的图片格式.润乾报表一方面可以生成 SVG 格式的统计图,另一方面也可以在 HTML5 中直接 ...

  7. sql 语句系列(月份的第一个星期的星期一和最后一个星期的星期一)[八百章之第二十一章]

    mysql select y.first_monday,CASE MONTH(ADDDATE(y.first_monday,28)) when mth then ADDDATE(y.first_mon ...

  8. redis 简单整理——redis 的列表基本结构和命令[四]

    前言 简单整理一下redis的列表. 正文 列表(list)类型是用来存储多个有序的字符串,如图2-18所示,a. b.c.d.e五个元素从左到右组成了一个有序的列表,列表中的每个字符串 称为元素(e ...

  9. 重新整理.net core 计1400篇[二] (.net core 改造控制台项目)

    前言 为.net core 命令行的基础上写的,如果有兴趣的话,可以去看我的.net core 前文. 下面介绍如何将.net core控制台转换为.net core web应用. 正文 如果我们要实 ...

  10. 什么是ip协议一

    前言 两节结束,为网络底层系列做铺垫. 首先来看一张图: IOS有七层,但是我们可以简化层4层,ip属于传输层,可以说是非常重要,下面简单的做一个介绍. 正文 ip的介绍: 1.ip是tcp/ip 协 ...