Comments (22)
- 指定 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 影响当前的父页面
from step-by-step.
1:html5中新增async(ie9以上;并且只能用于外部脚本js的引入)
2:html4中defer属性(只能用于外部脚本js的引入)
3:利用ajax请求js的代码并用eval执行
4:动态创建script标签
5:用iframe引入js
6:requirejs
7:import
8:define
from step-by-step.
<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);
}
}
from step-by-step.
- 动态创建script标签,可通过script的onreadyState监视加载。
- html5新增的async属性:可跟其他内容并行下载,限制ie9以上,只能加载外部js脚本。
- html4的defer,作用与async相同,兼容更好一点,但async只要加载完可立即执行,defer需等待在dom加载完毕后执行,在window.onload之前,其他没有添加defer属性的script标签之后。
- 利用XHR异步加载js内容并执行。
- iframe方式。
from step-by-step.
1.动态创建script标签
2.利用XHR异步加载js内容并执行
3.<script>标签的async="async"属性
4.<script>标签的defer="defer"属性
5.iframe方式
6.AJAX eval
from step-by-step.
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);
from step-by-step.
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(异步),进行请求
from step-by-step.
异步加载js脚本的方法
1、<script>标签的defer属性
<script src="main.js" defer></script>
2、<script>标签的async属性
<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)
}
}
}
from step-by-step.
- <script async> >= ie 9
- <script defer> >= ie 9
- 动态创建script标签
- AJAX eval(使用AJAX得到脚本内容,然后通过eval_r(xmlhttp.responseText)来运行脚本)
兼容所有浏览器。
from step-by-step.
参考前面大佬的
- 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)
}
}
from step-by-step.
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影响当前父页面的一种方式
from step-by-step.
异步加载JS的方式
- 动态创建<script>
(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文件
,且这种方式只能用<script>引入外部js。且引入的js中不能包含document.write
async: 异步下载后立即执行,H5新增的。按那个js先下载完先执行的远着
from step-by-step.
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
中执行;
from step-by-step.
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("加载完成!");
});
from step-by-step.
- H5新增属性 async
Chrome、Firefox、IE9&IE9+均支持(IE6~8不支持)。
- H4的属性 defer
兼容所有浏览器。
这两个方法的区别
1、defer脚本的执行会在window.onload之前,其他没有添加defer属性的script标签之后。
2、async会让脚本在下载完可用时立即执行,而defer脚本则会在dom加载完毕后执行,
3、async不能确保加载执行的顺序,多个 defer 脚本,会按照它们在页面出现的顺序加载
(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影响当前父页面的一种方式。
from step-by-step.
异步加载的很多
1.async 在html5新增的属性,谷歌、火狐、ie9(ie6-ie8)不支持
2.H4属性中的defer 兼容所有浏览器
3.两个方法的区别
1、defer脚本的执行会在window.onload之前,其他没有添加defer属性的script标签之后。
2、async会让脚本在下载完可用时立即执行,而defer脚本则会在dom加载完毕后执行,
3、async不能确保加载执行的顺序,多个 defer 脚本,会按照它们在页面出现的顺序加载
from step-by-step.
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)
}
}
from step-by-step.
浏览器加载JS文件的原理
浏览器加载Javascript脚本,主要通过<script>元素完成。
1.浏览器一边下载HTML网页,一边开始解析。
2.解析过程中,浏览器发现<script>元素,就暂停解析,把网页渲染的控制权转交给JS引擎。
3.如果<script>元素引用了外部脚本,就下载该脚本再执行,否则就直接执行代码。
4.JS引擎执行完毕,控制权交还渲染引擎,恢复解析HTML网页。
加载外部脚本时,浏览器会暂停页面渲染,等待脚本下载并执行完成,再继续渲染。因为JS代码可以修改
DOM,所以必须把控制权让给它。
将<script>标签放到中的做法,叫做同步加载,也叫阻塞加载,因为在加载JS脚本文件时,会阻塞浏览器解析HTML文档,等到下载并执行完毕以后再接着解析HTML文档。
如果加载时间过长,就会造成浏览器“假死”,页面一片空白。
放在中同步加载的JS文件不能对DOM进行操作,否则会产生错误,因为这个时候HTML还没有进行解析,DOM还没有生成。
异步加载
1.将<script>标签放到底部
这其实不算异步加载,但这也是常见的通过改变JS加载方式来提升页面性能的一种方式。
不会造成页面解析阻塞,就算加载时间过长,用户也可以看到页面,而不是一片空白,而且这个时候可以在脚本中操作DOM。
2.defer属性
通过给<script>标签设置defer属性,将脚本文件设置为延迟加载,当浏览器遇到带有defer属性的<script>标签时,会再开启一个线程去下载JS文件,同时继续解析HTML文档,等HTML全部解析完毕DOM加载完成之后,再去执行加载好的JS文件。
这种方式只适用于引用外部JS文件的<script>标签,可以保证多个JS文件的执行顺序就是它们在页面中出现的顺序,但是要注意,defer属性的JS文件不应该使用document.write方法。
3.async属性
async属性和defer属性类似,也会开启一个线程去下载JS文件,但是和defer不同的是,它会在下载后立刻执行,而不会等到DOM加载完成后再执行,所以还是会造成阻塞。
同样的,async也只适用于外部JS文件,也不能在js中使用document.write方法,但是对于多个带有async的JS文件,它不能像defer那样保证按顺序执行,它是哪个JS文件先下载完就先执行哪个文件。
- 动态创建<script>标签
(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
from step-by-step.
异步加载JS的方法
- <script defer>
这个布尔属性被设定用来通知浏览器该脚本将在文档完成解析后,触发 DOMContentLoaded 事件前执行。如果缺少 src 属性(即内嵌脚本),该属性不应被使用,因为这种情况下它不起作用。对动态嵌入的脚本使用
async=false
来达到类似的效果。
- <script async>
该布尔属性指示浏览器是否在允许的情况下异步执行该脚本。该属性对于内联脚本无作用 (即没有src属性的脚本)。
- JS异步创建
setTimeout(function () {
var script = document.createElement('script')
script.src = 'xxx';
document.querySelector('body').appendChild(script)
}, 0);
from step-by-step.
异步加载js脚本的方法
我自己能想到的
- defer (异步下载后,按照加载顺序执行脚本)
- async (异步下载后乱序执行)
- 使用XMLHttpRequest异步请求脚本
别人补充的
- 动态创建 script标签
let script = document.createElement('script');
script.src = "main.js";
document.body.appendChild(script);
- iframe方式
from step-by-step.
1.指定async属性
2.指定defer属性
defer要等到整个页面在内存中正常渲染结束,在window.onload之前执行
async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再进行渲染
如果有多个defer脚本,会按照顺序加载
如果多个async脚本,并不能保证加载顺序
3.利用XHR异步加载js内容并执行
4.动态创建script标签
5.iframe方式
from step-by-step.
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);
}
}
from step-by-step.
Related Issues (20)
- 寄生组合式继承的基本**是什么?有哪些优缺点? HOT 11
- 实现一个 JSON.stringify HOT 9
- 实现一个 JSON.parse HOT 9
- 实现一个观察者模式 HOT 10
- 使用CSS让一个元素水平垂直居中 HOT 11
- ES6模块和CommonJS模块有哪些差异? HOT 8
- 如何使用Proxy实现简单MVVM HOT 2
- 以下代码的输出的结果为: HOT 7
- 列举常见的JS和CSS兼容性问题
- 介绍下 Set、Map、WeakSet 和 WeakMap 的区别? HOT 1
- Vue组件间是怎么进行参数传递的? HOT 4
- 如果浏览器主线程一直被占据,那么setTimeout会什么时候执行
- rem、em、vh、vw 有什么区别
- flex-grow 与 flex-shrink 的计算规则
- while循环卡死和微任务卡死有什么区别
- sourcemap原理是什么
- 闭包会导致内存泄漏为什么还要使用?
- 前端怎么显示1G的图片甚至1T的图片
- 手写lodash的get方法
- setTimeout回调和fetch回调哪个先执行
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from step-by-step.