异步加载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 src="example.js"></script> | 立即加载 | 立即执行 | 阻塞 |
添加async | <script src="example.js"></script> | 异步加载: 后续文档的加载与 script 脚本的加载 并行进行 | 加载后立即执行 后续文档渲染与 script 脚本执行 并行进行 | 不阻塞 |
添加defer | <script src="example.js"></script> | 异步加载:仅加载不执行 后续文档加载与 script 脚本加载 并行进行 | 文档所有元素解析完成之后、DOMContentLoaded 事件触发执行之前 | 不阻塞 |
结论:defer和async的加载均是异步执行;但具有async属性的脚本,异步加载完成后立即执行,而有defer的脚本的执行在所有文档执行之后才执行,更符合大多数场景对应用脚本加载和执行的要求。
当存在多个有defer属性的脚本时,其执行顺序与加载顺序一致;对于async,它的加载后立即执行,脚本执行顺序与声明顺序无关,不适用于考虑依赖的应用脚本场景。
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 οnlοad="insertJS()">');
doc.close();