异步加载

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

从这张图里我们可以看到如下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. #并查集#JZOJ 4223 旅游

    题目 多次询问有多少个无序点对\((x,y)\), 满足至少有一条最大边权\(\leq d\)的路径 分析 离线询问,用并查集加边,每次产生的贡献为\(2*siz[x]*siz[y]\) 代码 #in ...

  2. Java 文件处理完全指南:创建、读取、写入和删除文件详细解析

    Java 文件操作 文件处理简介 文件处理是任何应用程序的重要部分.Java 提供了许多用于创建.读取.更新和删除文件的方法. Java 文件处理 Java 中的文件处理主要通过 java.io 包中 ...

  3. centos7.2 利用yum安装配置apache2.4多虚拟主机

    centos7.2 利用yum安装配置apache2.4多虚拟主机 标签: centosapacheyum 2017-01-10 21:01  3175人阅读  评论(0)  收藏  举报   分类: ...

  4. spring boot 手动value和自动注入配置的区别[五]

    前言 前面两篇中,写道我们注入配置的方式,是通过是注解的方式完成,如下: @ConfigurationProperties(prefix ="person") 这意味着: 我们写一 ...

  5. redis哨兵主备切换的数据丢失问题:异步复制、集群脑裂

    1.两种数据丢失的情况 主备切换的过程,可能会导致数据丢失 (1)异步复制导致的数据丢失 因为master -> slave的复制是异步的,所以可能有部分数据还没复制到slave,master就 ...

  6. background-blend-mode

    由于 mix-blend-mode 这个属性的强大,很多应用场景和动效的制作不断完善和被发掘出来,遂另起一文继续介绍一些使用 mix-blend-mode 制作的酷炫动画. CSS3 新增了一个很有意 ...

  7. 力扣704(java&python)-二分查找(简单)

    题目: 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1. 示例 1: 输入: ...

  8. HarmonyOS NEXT应用开发之深色跑马灯案例

    介绍 本示例介绍了文本宽度过宽时,如何实现文本首尾相接循环滚动并显示在可视区,以及每循环滚动一次之后会停滞一段时间后再滚动. 效果图预览 使用说明: 1.进入页面,检票口文本处,实现文本首尾相接循环滚 ...

  9. mPaas 研发流程和线上运维介绍

    简介: mPaas 研发流程和线上运维介绍 一. 背景 金融级移动开发平台 mPaaS[1](Mobile PaaS)为 App 开发.测试.运营及运维提供云到端的一站式解决方案,能有效降低技术门槛. ...

  10. Vineyard 加入 CNCF Sandbox,将继续瞄准云原生大数据分析领域

    简介: Vineyard 是一个专为云原生环境下大数据分析场景中端到端工作流提供内存数据共享的分布式引擎,我们很高兴宣布 Vineyard 在 2021 年 4 月 27 日被云原生基金会(CNCF) ...