我们知道渲染引擎遇到 script 标签会停下来,等加载并执行完该脚本,才继续向下渲染,这种传统js加载方式存在着明显的不足。当过多的js加载时,会严重影响页面渲染效率,一旦网速不好,那么整个网站将会等着,一直等待js加载执行,而不进行后续的渲染工作了。
有的时候在加载工具方法时,我们希望加载的同时不阻塞页面的渲染;有的时候有些工具方法按需加载,用到时再加载;这是就得用到js异步加载技术了。
JavaScript异步加载的三种方式
- defer异步加载(仅IE可用)
<!-- 1 -->
<script defer = "defer" src = "./index.js"></script>
<!-- 2 -->
<script defer = "defer">
//code
</script>
defer:遇到就去加载,但是要等DOM文档全部解析完才会被执行
- async异步加载
<script async = "async" src = "./index.js"></script>
async:遇到就去加载,加载完就去执行,不考虑DOM是否解析完毕!
async只能异步加载外部js,不能将js代码写在script标签内,让async去异步加载里面的js代码。
可同时使用async和defer,这样IE 4以上和其他浏览器都支持异步加载
<script src = "./js/tools.js" async defer></script>
- 手动封装,按需加载
手动封装一个方法,在需要的地方调用
// 手动封装异步加载js的方法
function asyncLoadScript(url, callback) {
var script = document.createElement('script');
script.type = 'text/javascript';
if (script.readyState) {//readyState是IE中的状态码
script.onreadystatechange = function () {
//绑定监听状态码的事件,IE状态码变成complete或者loaded,表示该元素加载完
if (script.readyState == "complete" || script.readyState == "loaded") {
callback();//回调函数,当script加载完后调用
}
}
} else {
//非IE 用onload事件,表示当script加载完时
script.onload = function () {
callback();//回调函数,当script加载完后调用
}
}
script.src = url;//放在这,是为了避免IE立即加载完,立即加载完就不再触发onreadystatechange
document.head.appendChild(script);//加载到页面中去
}
//执行
asyncLoadScript('./js/tools.js', function () {
//code
console.log('按照加载完了:' + url + '文件')
});
网友评论