一、异步加载script的好处

为了加快首屏响应速度,前端会采用代码切割、按需加载等方式优化性能。异步加载script也是一种前端优化的手段。

就好比如果我的页面其中一个功能需要打开地图,但是地图的js插件包是非常大的,而如果用户不用地图功能的时候,我们当然不能再给它加载js地图包,白白让他多花等待时间岂不是很冤枉!于是我们可以动态插入script,当用户点击了某个按钮的时候,再新建script标签,引入地图js资源。

下面介绍下异步加载script的几种方式。

二、异步加载script的方式

1. 异步加载JS
    getMap.onclick = function(){
//获得需要插入的位置
var oDiv = document.getElementById('div');
//异步创建script
var script = document.createElement('script'); script.src = 'https://map.baidu.com/...' oDiv.appendChild(script);
}
2. script标签加上defer或async

script标签存在两个属性,defer和async,加上两个属性之后,在js真正执行之前都不会阻止html的加载。因此script标签的使用分为三种情况:

  • 没有defer或async属性,浏览器会立即加载并执行相应的脚本。也就是说在渲染script标签之后的文档之前,不等待后续加载的文档元素,读到就开始加载和执行,此举会阻塞后续文档的加载;
<script src="example.js"></script>
  • 有了async属性,表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的,即异步执行;
<script async src="example.js"></script>
  • 有了defer属性,加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),js脚本的执行需要等到文档所有元素解析完成之后,DOMContentLoaded事件触发执行之前。
<script defer src="example.js"></script>

下图可以直观的看出三者之间的区别:



其中蓝色代表js脚本网络加载时间,红色代表js脚本执行时间,绿色代表html解析。

从图中我们可以明确一下几点:

  1.defer和async在网络加载过程是一致的,都是异步执行的;

  2.两者的区别在于脚本加载完成之后何时执行,可以看出defer更符合大多数场景对应用脚本加载和执行的要求;

  3.如果存在多个有defer属性的脚本,那么它们是按照加载顺序执行脚本的;而对于async,它的加载和执行是紧紧挨着的,无论声明顺序如何,只要加载完成就立刻执行,它对于应用脚本用处不大,因为它完全不考虑依赖。

转载于:https://www.cnblogs.com/neusc/archive/2016/08/12/5764162.html

3. 通过 ajax 去获取 js 代码,然后通过 eval 执行
window.onload = function(){
//1.创建XMLHttpRequest对象并考虑兼容性
var xhr;
if(window.XMLHttpRequest){
//通用浏览器
xhr = new XMLHttpRequest();
}
else{
//IE5/6
xhr = new ActiveXObject('Miscrosoft.XMLHttp')
} //2.设置请求方式
let url = '';
xhr.open('get', url, true);//异步请求 //3.发送请求
xhr.send(); //4.回调函数
xhr.onreadyStateChange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
let script = xhr.responseText;
eval(script); //异步加载script
}
}
}
4. 创建并插入 iframe,让它异步执行 js
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
var doc = iframe.contentWindow.document;
doc.open().write('<body onload="insertJS()">');
doc.close();

异步加载script,提高前端性能(defer和async属性的区别)的更多相关文章

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

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

  2. <script>标签里的defer和async属性 区别(待补充)

    defer与async的区别(表格显示): table th:first-of-type { width: 150px; } table th:nth-of-type(2) { } 区别 defer ...

  3. Javascript 异步加载详解(转)

    本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy execution),async 属 ...

  4. 谈谈异步加载JavaScript

    前言 关于JavaScript脚本加载的问题,相信大家碰到很多.主要在几个点—— 1> 同步脚本和异步脚本带来的文件加载.文件依赖及执行顺序问题 2> 同步脚本和异步脚本带来的性能优化问题 ...

  5. Javascript 异步加载详解

    Javascript 异步加载详解 本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy ...

  6. javascript异步加载详解(转)

    本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy execution),async 属 ...

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

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

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

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

  9. 异步加载js的三种方法

    js加载时间线 : 它是根据js出生的那一刻开始记录的一系列浏览器按照顺序做的事,形容的就是加载顺序,可以用来优化什么东西,理论基础,背下来. 1.创建Document对象,开始解析web页面.解析H ...

随机推荐

  1. centos 6.5 防火墙开放指定端口

    清除防火墙规则:iptables  -F 关闭防火墙 /etc/init.d/iptables stop 关闭防火墙开机自启:chkconfig iptables off 查看iptables 是否开 ...

  2. How to use Nissan consult 3 plus to check, make key and program?

    How to use Nissan consult 3 plus to test Nissan? Firstly: get one particular Nissan consult 3 plus. ...

  3. 洛谷 P1015 回文数

    #include<iostream> #include<cstdio> #include<cmath> #include<string> #includ ...

  4. MyEclipse配置默认自带的HTML/JSP代码格式化

    MyEclipse自带默认的HTML/JSP代码格式化并不适合个人开发习惯,因此特意配置如下: 设置行宽为:720(直接加10倍) 使用tabs缩进,单位:1 缩进标签元素要求删除: a开头:a. b ...

  5. 计算概论(A)/基础编程练习2(8题)/6:数组逆序重放

    #include<stdio.h> int main() { // 输入n个整数 ; scanf("%d", &n); // 循环读入元素 while(scan ...

  6. ES6知识整理(10)--class的继承

    (这是es6的第10篇文章.说真的这样的总结之后虽然直观了许多,但是消耗的时间有点长,或许是知识比较复杂的原因吧) 类的继承 有个A类,B类继承A类,那B类实例就可以使用A类实例的所以属性和方法.不包 ...

  7. Django中程序中图片资源的路径问题(static文件夹的放置)

    步骤1:在settings.py文件的最后加上以下内容: STATIC_URL = '/static/'STATIC_ROOT = os.path.join(os.path.dirname(__fil ...

  8. php 数字变汉字

    //数字变汉字 function getTheWord($num) { $arr_n = array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九', ...

  9. java泛型中<?>和<T>区别

    public static void printColl(ArrayList<?> al){                Iterator<?> it = al.iterat ...

  10. 2、pandas的value_counts()和describe()

    一.value_counts pandas 的value_counts()函数可以对Series里面的每个值进行计数并且排序. value_counts是计数,统计所有非零元素的个数,默认以降序的方式 ...