我们都知道渲染引擎遇到 script 标签会停下来,等到执行完脚本,继续向下渲染,如下:
<script type="text/javascript" src="../../libs/public.js" ></script>
这样会阻止浏览器的后续解析,只有当前加载完成才能进行下一步操作,所以默认同步执行才是安全的。但是这样如果JS中有输出document内容、修改dom、重定向的行为,就会造成页面阻塞。所以一般建议把<script>标签放在<body>结尾处,这样尽可能减少页面阻塞。
异步加载又被称为非阻塞加载,浏览器在下载JS的同时,还会进行后续页面处理。那么如何实现js异步加载呢?下面整理了多种实现方案供大家参考:
 
方法一:Script Dom Element
(function(){
var scriptEle = document.createElement("script");
scriptEle.type = "text/javasctipt";
scriptEle.async = true;
scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
var x = document.getElementsByTagName("head")[0];
x.insertBefore(scriptEle, x.firstChild);
})();

  

<async>属性是HTML5中新增的异步支持。此方法被称为Script DOM Element方法
(function(){;
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();

  

但是这种加载方式执行完之前会阻止onload事件的触发,而现在很多页面的代码都在onload时还执行额外的渲染工作,所以还是会阻塞部分页面的初始化处理。
 
方法二:onload时的异步加载
(function(){
if(window.attachEvent){
window.attachEvent("load", asyncLoad);
}else{
window.addEventListener("load", asyncLoad);
}
var asyncLoad = function(){
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
}
})();

  

这种方法只是把插入script的方法放在一个函数里面,然后放在window的onload方法里面执行,这样就解决了阻塞onload事件触发的问题。
注:DOMContentLoaded与load的区别。前者是在document已经解析完成,页面中的dom元素可用,但是页面中的图片,视频,音频等资源未加载完,作用同jQuery中的ready事件;后者的区别在于页面所有资源全部加载完毕。
 
方法三:$(document).ready()
需要引入jquery,兼容所有浏览器  
$(document).ready(function() {
alert("加载完成!");
});

  

 
方法四:<script>标签的async="async"属性
  • async属性是HTML5新增属性,需要Chrome、FireFox、IE9+浏览器支持
  • async属性规定一旦脚本可用,则会异步执行
  • async属性仅适用于外部脚本
  • 此方法不能保证脚本按顺序执行
  • 他们将在onload事件之前完成
<script type="text/javascript" src="xxx.js" async="async"></script>

  

方法五:<script>标签的defer="defer"属性
  • defer属性规定是否对脚本执行进行延迟,直到页面加载为止
  • 如果脚本不会改变文档的内容,可将defer属性加入到<script>标签中,以便加快处理文档的速度
  • 兼容所有浏览器
  • 此方法可以确保所有设置了defer属性的脚本按顺序执行
<script type="text/javascript" defer></script>

  

方法六:es6模块type="module"属性
浏览器对于带有type=”module”的<script>,都是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本,等同于打开了<script>标签的defer属性 。如下:
 
<script type="module" src="XXX.js"></script>

  

ES6模块允许内嵌在网页中,语法行为与加载外部脚本一致,如下:
<script type="module">
import utils from "./utils.js";
// other code
</script>

  

14. 异步加载Js的方式有哪些?的更多相关文章

  1. 请给出异步加载js方案

    请给出异步加载js方案,不少于两种 默认情况javascript是同步加载的,也就是javascript的加载时阻塞的,后面的元素要等待javascript加载完毕后才能进行再加载,对于一些意义不是很 ...

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

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

  3. 网页性能优化之异步加载js文件

    一个网页的有很多地方可以进行性能优化,比较常见的一种方式就是异步加载js脚本文件.在谈异步加载之前,先来看看浏览器加载js文件的原理. 浏览器加载 JavaScript 脚本,主要通过<scri ...

  4. 异步加载js

    //异步加载js function loadScript(url,callback){ var script = document.createElement("script"); ...

  5. HTML5中script的async属性异步加载JS

    HTML5中script的async属性异步加载JS     HTML4.01为script标签定义了5个属性: charset 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer 可 ...

  6. angularLoad(用以异步加载js文件)

    angularLoad(用以异步加载js文件) 使用方法: 1.执行命令 下载 lib npm install angular-load --save 2.index.html引用js <scr ...

  7. phoneGap异步加载JS失败

    现在正在做一个phoneGap项目,安卓平台,有个异步加载JS总是失败,phoneGap也不好调试,一个问题纠结了一下午 最后找了半天,找到了原因,因此写本文记录一下,也顺便帮帮遇到同样问题的人 原因 ...

  8. 异步加载js文件的方法

    # 异步加载js文件 - js的加载默认是同步的,因为js是单线程执行,只能完成一件再执行下一件. - 一些外部引入的js文件可以因为文件太大,在加载资源的过程中会影响dom元素的加载,影响了用户体验 ...

  9. 异步加载JS几种方式

    默认情况javascript是同步加载的,也就是javascript的加载时阻塞的,后面的元素要等待javascript加载完毕后才能进行再加载,对于一些意义不是很大的javascript,如果放在页 ...

随机推荐

  1. 页面布局 frameset元素

    frameset.html: <!DOCTYPE html><html lang="en"><head> <meta charset=&q ...

  2. consul event

    Command: consul event event 命令提供了一种机制来将自定义用户事件触发到整个数据中心. 这些事件对Consul来说是不透明的,但是它们可以用来构建脚本基础架构来执行自动化部署 ...

  3. windows7 Sql server 2012 尝试读取或写入受保护的内存。这通常指示其他内存已损坏的修复

    项目中,使用了sql server2012数据库,服务端是2012,客户端如果是2008的话,就会报错: 索引错误. 没办法,就安装了sql server2012客户端.但是还是报错,无法连上数据库服 ...

  4. Hyperledger Fabric Orderer节点启动

    Orderer 节点启动通过 orderer 包下的 main() 方法实现,会进一步调用到 orderer/common/server 包中的 Main() 方法. 核心代码如下所示. // Mai ...

  5. 【原创】请不要对Boost Format使用Byte作为参数

    曾几何时我们可以肆无忌惮的对sprintf传入BYTE等类型作为参数,只要你指定的为%D即可打印出对应的数字 但是boost format不可以,当你发生类型截断,错误,异常,请尽快查看你传入的类型是 ...

  6. Spark的job调优(1)

    本文翻译之cloudera的博客,本系列有两篇,第二篇看心情了 概论 当我们理解了transformation,action和rdd后,我们就可以写一些基础的spark的应用了,但是如果需要对应用进行 ...

  7. 高级软件测试技术(测试管理工具实践day3)

    昨天在晚上由于安装bugzilla中有一些小问题,并且需要手工安装很多perl模块  ppm install XXX(模块名称).一直到过了十二点就没有继续更博了.所以由今天更. 继昨天的安装问题之后 ...

  8. App测试从入门到精通之功能测试

    App的功能测试指的是针对软件需求以及用户要求针对APP功能进行测试.简单点理解就是保证App功能的正确性,不要系统出现Bug.让用户用户的舒服,用的爽!好了,我们看下关于App的功能测试要点有哪些? ...

  9. MATLAB读取写入文本数据最佳方法 | Best Method for Loading & Saving Text Data Using MATLAB

    MATLAB读取文件有很多方法.然而笔者在过去进行数据处理中,由于函数太多,相互混杂,与C#,Python等语言相比,反而认为读取文本数据比较麻烦.C#和Python等高级语言中,对于大部分的文本数据 ...

  10. repeater+aspnetpager 组合分页

    页面代码 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="TF_Product. ...