Step-By-Step
Step-By-Step copied to clipboard
异步加载 js 脚本的方法有哪些?
1:html5中新增async(ie9以上;并且只能用于外部脚本js的引入) 2:html4中defer属性(只能用于外部脚本js的引入) 3:利用ajax请求js的代码并用eval执行 4:动态创建script标签 5:用iframe引入js 6:requirejs 7:import 8:define
- 指定 async 属性 指定 async 属性的目的是不让页面等待两个脚本下载和执行,从而异步加载页面其他内容。 为此,建议异步脚本不要在加载期间修改 DOM。 执行顺序:让脚本在加载完可用时立即执行,异步脚本一定会在页面的 load 事件前执行,但可能会在 DOMContentLoaded 事件触发之前或之 后执行。
<!DOCTYPE html>
<html>
<head>
<title>Example HTML Page</title>
<script type="text/javascript" async src="example1.js"></script> <script type="text/javascript" async src="example2.js"></script>
</head>
<body>
<!-- 这里放内容 --> </body>
</html>
- defer属性 执行顺序:在dom加载完毕后执行,defer脚本的执行会在window.onload之前,其他没有添加defer属性的script标签之后
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
</head>
<script>
window.onload = function() {
console.log("window.onload");
}
</script>
<script src="js/defer.js" defer></script>
<script>
console.log("normal");
</script>
<body>
</body>
</html>
- 利用XHR异步加载js内容并执行
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
</head>
<script>
var xhr = new XMLHttpRequest();
xhr.open("get", "js/defer.js",true)
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
eval(xhr.responseText);
}
}
</script>
<body>
</body>
</html>
- 动态创建script标签
var script = document.createElement("script");
script.src = "js/test.js";
document.head.appendChild(script);
- iframe 方式 用 iframe 加载一个同源的子页面,让子页面的 js 影响当前的父页面
- 动态创建script标签,可通过script的onreadyState监视加载。
- html5新增的async属性:可跟其他内容并行下载,限制ie9以上,只能加载外部js脚本。
- html4的defer,作用与async相同,兼容更好一点,但async只要加载完可立即执行,defer需等待在dom加载完毕后执行,在window.onload之前,其他没有添加defer属性的script标签之后。
- 利用XHR异步加载js内容并执行。
- iframe方式。
1.动态创建script标签 2.利用XHR异步加载js内容并执行 3.
1.给script标签添加defer属性
- defer属性会让js并行下载,但是要等到HTML解析完成之后,在window.onload事件之前执行
- 添加了defer属性的js文件执行的顺序和在文档中定义的顺序一样
<script src="../your_file.js" defer></script>
2.给script标签添加async属性
- async属性会让js并行下载,但是js文件下载完成之后立刻执行无论html是否解析完毕
- 添加了async属性的js文件执行顺序不能保证
<script src="../your_file.js" async></script>
3.动态创建script标签
- 和img标签不一样,设置了script的src并不会开始下载,而是要添加到文档中Js文件才会开始下载
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'your_file.js';
// 只有添加到html文件中才会开始下载
document.body.append(script);
4.使用xhr脚本注入
- 会受到同源策略的限制
var xhr = new XMLHttpRequest();
xhr.open("get", "your_file.js", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'your_file.js';
script.text = xhr.responseText;
// 只有添加到html文件中才会开始下载
document.body.append(script);
}
}
}
xhr.send(null);
1.脚本增加async或者defer属性
区别是async加载完成便会执行,defer要等到html解析完成之后执行
2.动态添加script标签
js代码中动态添加script标签,并将其插入页面
var script = document.createElement("script"); script.src = "a.js"; document.head.appendChild(script);
3.使用xhr异步加载并执行js
将参数设置为true(异步),进行请求
异步加载js脚本的方法
1、
<script src="main.js" defer></script>
2、
<script src="main.js" async></script>
3、动态创建script标签
let script = document.createElement('script');
script.src = "main.js";
document.body.appendChild(script);
4、通过XHR异步加载js
let xhr = new XMLHttpRequest();
xhr.open('get', 'js/main.js', true);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 ) {
if(xhr.status === 200) {
console.log(xhr.responseText)
}
}
}
- 动态创建script标签
- AJAX eval(使用AJAX得到脚本内容,然后通过eval_r(xmlhttp.responseText)来运行脚本) 兼容所有浏览器。
参考前面大佬的
- h5之前通过script标签的defer属性
<script src="index.js" defer></script>
- h5之后script增加了async属性
<script src="index.js" async></script>
- 通过动态创建script标签
let script = document.createElement('script');
script.src = "index.js";
document.body.appendChild('script');
- 通过XHR异步加载
let xhr = new XMLHttpRequest();
xhr.open('get', 'index.js', true);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
}
}
1.在html5中,script新增了async的属性(只支持ie9以上的浏览器,只能用于加载外部js脚本) 2.在html4中,有一个defer属性,该属性的兼容性更好一点,但是与async一样,可以让js脚本实现异步加载,同样只能用于加载外部js脚本 3.利用XHR异步加载js内容并执行
<script>
var xhr = new XMLHttpRequest();
xhr.open("get", "js/defer.js",true)
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
eval(xhr.responseText);
}
}
</script>
4.动态创建script标签
var script = document.createElement("script");
script.src = "js/test.js";
document.head.appendChild(script);
5.iframe方式,利用iframe加载一个同源的子页面,让子页面内的js影响当前父页面的一种方式
<script>
标签中增加 async
(html5) 或者 defer
(html4) 属性,脚本就会异步加载。
<script src="XXX.js" defer></script>
<script src="XXX.js" async></script>
defer
和 async
的区别在于:
-
defer
要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),在window.onload 之前执行; -
async
一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。 - 如果有多个
defer
脚本,会按照它们在页面出现的顺序加载 - 多个
async
脚本不能保证加载顺序
动态创建 script
标签
动态创建的 script ,设置 src 并不会开始下载,而是要添加到文档中Js文件才会开始下载。
let script = document.createElement('script');
script.src = 'XXX.js';
// 添加到html文件中才会开始下载
document.body.append(script);
使用xhr异步加载并执行js
let xhr = new XMLHttpRequest();
xhr.open("get", "js/defer.js",true)
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
eval(xhr.responseText);
}
}
异步加载JS的方式
- 动态创建
(function () {
var dom = document.createElement('script')
dom.type = 'text/javascript'
dom.async = true
dom.src= 'file.js'
var head = document.getElementByTagName('head')[0],
head.insertBefore(dom, head.firstChild)
})()
(function () {
if (window.attachEvent) {
window.attachEvent('load', asyncload)
} else {
window.addEventListener('load', asyncload)
}
var asyncload = function () {
var dom = document.createElement('script')
dom.type = 'text/javascript'
dom.async = true
dom.src='file.js'
var s = document.getElementByTagNames('script')[0]
s.parentNode.insertBefore(dom, s)
}
}) ()
第一种方法,执行完之前会阻止onload事件触发,可能会在onload执行额外的渲染工作, 第二种方法不会阻止onLoad的触发。
题外话: window.DOMContentLoaded 和 window.onload 的区别。前者是DOM解析完毕触发,但一些图片,视频还没有加载完,后者是页面完全加载完毕
- XHR Eval :通过ajax获取js的内容,然后eval 插入执行
var xhr ;
if (XMLHttpRequest) {
xhr = new XMLHttpRequest()
} else {
xhr = new ActiveXObject('MIcrosoft.XMLHTTP')
}
xhr.open('get', 'file.js', true)
xhr.send()
xhr.onreadystatechange = function () {
if(xhr.readyState === 4) {
eval(xhr.responseText)
}
}
- 利用iframe 引入
var iframe = document.createElement('iframe')
document.body.appendChild(iframe)
var doc = iframe.contentWindow.document
doc.open().write('<body onload=function()>');
doc.close()
- defer 和 async
defer :浏览器会并行下载js, 等Html全部解析完毕,DOM加载完成后,再去执行js文件 ,且这种方式只能用
async: 异步下载后立即执行,H5新增的。按那个js先下载完先执行的远着
1.script
标签中增加 async
和 defer
属性;
-
defer
属性:异步下载文件,按照顺序执行带有defer
的属性的script
标签;在文档渲染完毕后,DOMContentLoaded
之前执行; -
async
属性:先加载完先执行;执行时,会阻塞文档渲染;
2.动态创建 script
标签;
3.父窗口插入 iframe
元素,在 iframe
中加载js;
4.document.write
;
5.XHR Injection
方式。创建 script
元素插入到 DOM 结构中,ajax 请求成功后设置 script.text
;
6.XHR eval
方式。ajax 请求成功后放在 eval
中执行;
1: 在html5中,script新增了async的属性,script添加了该属性之后,下载脚本时将可以与页面其他内容并行下载,但是该属性必须在ie9以上的浏览器中才可以使用,并且只能用于加载外部js脚本。
<script src="js/async.js" async></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js" async="async"></script>
2: 同样,在html4中也有一个defer属性,该属性的兼容性更好一点,但是与async一样,可以让js脚本实现异步加载,同样只能用于加载外部js脚本。
<script src="js/defer.js" defer></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js" defer="defer"></script>
asyc与defer属性的不同点是:async会让脚本在加载完可用时立即执行,而defer脚本则会在dom加载完毕后执行,defer脚本的执行会在window.onload之前,其他没有添加defer属性的script标签之后。
3: 利用XHR异步加载js内容并执行
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
</head>
<script>
var xhr = new XMLHttpRequest();
xhr.open("get", "js/defer.js",true)
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
eval(xhr.responseText);
}
}
</script>
<body>
</body>
</html>
4:动态创建script标签
function loadScript(url, callback){
var script = document.createElement("script");
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { // Others: Firefox, Safari, Chrome, and Opera
script.onload = function(){
callback();
};
}
script.src = url;
document.body.appendChild(script);
}
该方式还可以通过script的onreadyState监视加载的状态。
5:iframe方式,利用iframe加载一个同源的子页面,让子页面内的js影响当前父页面的一种方式。
6: 延迟加载
// 5秒后执行
varstart = Number(newDate());
while(start + 5000 > Number(newDate())){//执行JS}
7: $(document).ready()
需要引入jquery
兼容所有浏览器
$(document).ready(function() {
alert("加载完成!");
});
- H5新增属性 async Chrome、Firefox、IE9&IE9+均支持(IE6~8不支持)。
- H4的属性 defer 兼容所有浏览器。
这两个方法的区别 1、defer脚本的执行会在window.onload之前,其他没有添加defer属性的script标签之后。 2、async会让脚本在下载完可用时立即执行,而defer脚本则会在dom加载完毕后执行, 3、async不能确保加载执行的顺序,多个 defer 脚本,会按照它们在页面出现的顺序加载
3.动态创建script标签
(function () {
var s = document.createElement_x('script');
s.type = 'text/javascript';
s.src = "http://code.jquery.com/jquery-1.7.2.min.js";
var tmp = document.getElementsByTagName_r('script')[0];
tmp.parentNode.insertBefore(s, tmp);
})();
4.XHR异步加载js
var xhr = new XMLHttpRequest();
xhr.open("get", "xxxx.js", true)
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
eval(xhr.responseText);
}
}
5.iframe方式,利用iframe加载一个同源的子页面,让子页面内的js影响当前父页面的一种方式。
异步加载的很多 1.async 在html5新增的属性,谷歌、火狐、ie9(ie6-ie8)不支持
2.H4属性中的defer 兼容所有浏览器
3.两个方法的区别
1、defer脚本的执行会在window.onload之前,其他没有添加defer属性的script标签之后。
2、async会让脚本在下载完可用时立即执行,而defer脚本则会在dom加载完毕后执行,
3、async不能确保加载执行的顺序,多个 defer 脚本,会按照它们在页面出现的顺序加载
script标签有两个属性 defer 和async
defer 并行加载脚本,在解析该 script标签时并不会阻止文档的渲染 ,defer属性的script脚本必须等到dom结构渲染完毕才可以执行。
async
同步加载脚本,当解析该脚本时,会将该脚本的内容解析完毕之后,再去进行dom的绘制,造成文档加载阻塞
常见的异步加载脚本的方式
1. 动态创建scipt标签:
var script = document.creamentElement('script');
script.src='a.js'
document.body.append(script)
2 .XHR异步加载:
var xhr =new xhrHttpRequest()
xhr.open(get, 'a.js', true)
xhr.send()
xhr.onreadystatechange=function(){
if(xhr.status===200 || xhr.readyState===4){
eval(xhr.responseText)
}
}
浏览器加载JS文件的原理 浏览器加载Javascript脚本,主要通过
将
异步加载 1.将 这其实不算异步加载,但这也是常见的通过改变JS加载方式来提升页面性能的一种方式。 不会造成页面解析阻塞,就算加载时间过长,用户也可以看到页面,而不是一片空白,而且这个时候可以在脚本中操作DOM。 2.defer属性 通过给
3.async属性 async属性和defer属性类似,也会开启一个线程去下载JS文件,但是和defer不同的是,它会在下载后立刻执行,而不会等到DOM加载完成后再执行,所以还是会造成阻塞。 同样的,async也只适用于外部JS文件,也不能在js中使用document.write方法,但是对于多个带有async的JS文件,它不能像defer那样保证按顺序执行,它是哪个JS文件先下载完就先执行哪个文件。
- 动态创建
(function(){
var scriptElement=document.createElement("script");
scriptElement.type="text/javascript";
scriptElement.async=true;
scriptElement.src="http://cdn.bootscss.com/jquery/3.0.0-beta1/jquery.min.js";
var x=document.getElementByTagName("head")[0];
x.insertBefore(scriptElement,x.firstChild);
})()
或者
(function(){
if(window.attachEvent){//针对IE
window.attachEvent("onload",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.getElementByTagName('script')[0];
s.parentNode.insertBefore(ga,s);
}
})();
attachEvent和addEventListener的区别 https://www.cnblogs.com/dacuotecuo/p/3510823.html
第一种方法在脚本执行完之前,还是会阻止onload事件的触发,第二种则不会。 window.DOMContentLoaded和window.onload区别 前者是DOM解析完毕之后触发,JS可以获取到DOM引用,但是页面中的一些资源比如图片和视频还没有加载完成,作用同jQuery中的ready事件。后者则是页面全部加载完毕,包含各种资源。
何时用defer何时用async? 两者选择要看脚本间有没有依赖关系,有依赖要保证执行顺序,用defer没有依赖的话用async。 两者同时使用defer失效。两者都不能用document.write会导致整个页面被清除。
5.XHR异步加载
var xhr =new xhrHttpRequest()
xhr.open(get, 'a.js', true)
xhr.send()
xhr.onreadystatechange=function(){
if(xhr.status===200 || xhr.readyState===4){
eval(xhr.responseText)
}
}
转载自:酥风 https://juejin.im/post/5bcdaed7e51d457a8254e1b7
异步加载JS的方法
这个布尔属性被设定用来通知浏览器该脚本将在文档完成解析后,触发 DOMContentLoaded 事件前执行。如果缺少 src 属性(即内嵌脚本),该属性不应被使用,因为这种情况下它不起作用。对动态嵌入的脚本使用
async=false
来达到类似的效果。
该布尔属性指示浏览器是否在允许的情况下异步执行该脚本。该属性对于内联脚本无作用 (即没有src属性的脚本)。
- JS异步创建
setTimeout(function () {
var script = document.createElement('script')
script.src = 'xxx';
document.querySelector('body').appendChild(script)
}, 0);
异步加载js脚本的方法
我自己能想到的
- defer (异步下载后,按照加载顺序执行脚本)
- async (异步下载后乱序执行)
- 使用XMLHttpRequest异步请求脚本
别人补充的
- 动态创建 script标签
let script = document.createElement('script');
script.src = "main.js";
document.body.appendChild(script);
- iframe方式
1.指定async属性 2.指定defer属性 defer要等到整个页面在内存中正常渲染结束,在window.onload之前执行 async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再进行渲染 如果有多个defer脚本,会按照顺序加载 如果多个async脚本,并不能保证加载顺序 3.利用XHR异步加载js内容并执行 4.动态创建script标签 5.iframe方式
defer 属性& anync
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>defer</title>
<script>
window.onload = function() {
console.log("window.onload");
}
</script>
<script src="./defer.js" defer></script>
<script src="./defer.js" async></script>
</head>
<body>
</body>
</html>
动态的创建js
(function(){
var dom = document.createElement('script');
dom.type ='text/javascript';
dom.async = true;
dom.src= 'file.js';
head = document.getElementsByTagName('head')[0];
head.insertBefore(dom,head.firstChild)
})()
XHR
let xhr = new XMLHttpRequest();
xhr.open('get','index.js',true)
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText);
}
}