js异步加载
输入url后发生了什么
在讲解异步加载之前,我们先要了解,当我们将url输入后,页面发生了什么。
- 找ip
- 输入url
- 找缓存(浏览器->系统->路由器->hosts文件)
- 缓存中没有则DNS解析得到ip
- 发请求
- 构造http请求
- 封装在tcp包
- 网络传输(传输层、网络层、数据链路层、物理层)
- 服务器
- 构建页面
- 服务器返回数据
- 构建DOM,过程中遇到JS脚本优先JS脚本
- 构建CSSOM
- CSSOM和DOM合并渲染
- 布局
- 渲染页面
同步加载
平常编写代码时,我们常常写一个<script></script>
将代码包裹起来,这种情况会导致一个问题,JS默认情况下是同步加载的,在构建DOM之时,浏览器要先加载JS,之后再渲染页面,所以一旦JS出现阻塞,就会影响整个页面的构建。
异步加载
异步加载即浏览器在下载js时,还可以同时进行页面的处理。
-
defer:
- 等待DOM解析完开始执行
- 只支持IE
<script type="text/javascript" scr="" defer="defer"></script>
-
async:
- 只能加载外部脚本
- 异步加载,加载完就执行,所以不能保证脚本执行顺序
- 不兼容IE8及以下
async function fn()
-
封装一个函数兼容性的异步加载js文件并且可以按需执行该文件里面的函数(按需加载)
<script>
function loadScript(url,callback){
//url是按需加载的js文件
//callback是按需加载的js文件中某个函数
// 1. 创建一个script标签
var script = document.createElement('script');
// 处理ie的兼容
if(script.readyState){
script.onreadystatechange = function(){
// 如果script已经下载完成
if(script.readyState == 'complete' || script.readyState == 'loaded'){
callback();
}
}
}else{
// 监听script的下载的状态 当状态变为下载完成后 再执行callback
script.onload = function(){
callback();
}
}
//在后面引入的目的是如果在IE上如果下载太快(比读程序还快)
//IE的readystatechange 事件检测状态码的时候,它早已经从loading变成complete或者loaded(以极快的速度加载完了文件,你还没来得及检测)
// 那你再检测它就不会变了,它一直都是complete或者loaded
//这个时候就是马后炮了,检测也没用了。
// 2. 给script标签添加src 引入一个js文件
script.src = url;
// 3. 追加到body
document.body.appendChild(script);
}
</script>