异步加载js 和 js时间线介绍

异步加载jsjs加载的缺点:加载工具方法没必要阻塞文档, 过多js加载会影响页面效率, 一旦网速不好, 那么整个网站将等待js加载而不进行后序渲染工作.
有些工具方法需要按需加载, 用到再加载, 不用不加载.javascript异步加载的三种方案1 . defer异步加载, 但要等到dom文档全部加载完才会被执行. 只有ie能用, 也可以将代码写到内部.

异步加载js

js加载的缺点:

加载工具方法没必要阻塞文档, 过多js加载会影响页面效率, 一旦网速不好, 那么整个网站将等待js加载而不进行后序渲染工作.
有些工具方法需要按需加载, 用到再加载, 不用不加载.

javascript异步加载的三种方案

1 . defer异步加载, 但要等到dom文档全部加载完才会被执行. 只有ie能用, 也可以将代码写到内部.

1
<script type = "text/javascript" src="##.js" defer="defer"></script>

2 . async异步加载, 加载完就执行, async只能加载外部脚本, 不能把js写在script标签里.

1
<script type = "text/javascript" src="##.js" aysnc="aysnc"></script>

3 . 创建script, 插入到dom中, 加载完毕后callBack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var script = document.createElement('script');
script.type = "text/javascript";
script.src = "tools.js";
if(script.readyState) {
script.onreadystatechange = function () {//ie
if(script.readyState == 'complete' || script.readyState == 'loaded'){
text();//某个函数
}
}
}else{
script.onload = function () {
text();
}
}
document.head.appendChild(script);

现在我们写个通用的异步加载函数.适用于ie和目前的通用浏览器.
注意: 我调整了script.src的位置, 因为如果数据量太小, 导致加载瞬间完成的话, 在if里面的语句是不会进行的, 因此我们先绑定事件然后再开始下载文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* 异步加载事件
* 2016.12.31
*/
function loadScript(url, callback){
var script = document.createElement('script');
script.type = "text/javascript";
if(script.readyState) {
script.onreadystatechange = function () {//ie
if(script.readyState == 'complete' || script.readyState == 'loaded'){
callback();//某个函数
}
}
}else{
script.onload = function () {
callback();
}
}
script.src = url;
document.head.appendChild(script);
}

再这里我们还需要注意一个问题

1
loadScript('tools.js', text);

如果我们这样运用函数可以吗, 答案是不可以的, 因为当解析到这一步时, 这里的text函数是在tools.js中定义的, 因此如果我们直接传text进去会发生未定义错误, 所以正确的使用上述函数的方法为.

1
2
3
loadScript('tools.ja', function() {
text();
});

js加载时间线

  1. 创建Document对象, 开始解析web页面, 解析HTML元素和他们的文本内容后添加Element对象和Text节点到文档中, 这个阶段document.readyState = ‘loading’.
  2. 遇到link外部css, 创建线程加载, 并继续解析文档.
  3. 遇到script外部js, 并且没有acync, defer, 浏览器加载, 并阻塞, 等待js加载完成并执行该脚本, 然后继续解析文档.
  4. 遇到script外部js, 并且没有async, defer, 浏览器创建线程加载, 并继续解析文档, 对于async属性的脚本, 脚本加载完成后立即执行. (异步加载禁止使用document.write( )).
  5. 遇到img等, 先正常解析dom结构, 然后浏览器异步加载src, 并继续解析文档.
  6. 当文档解析完成, document.readState = ‘interactive’.
  7. 文档解析完成后, 所有设置有defer的脚本会按照顺序执行. (注意与async的不同, 但同样禁止使用document.write( ))
  8. document对象触发DOMContentLoaded事件, 这也标志着程序执行从同步脚本执行阶段, 转化为事件驱动阶段.
  9. 当所有async的脚本加载完成并执行后, img等加载完成后, document.readyState = ‘complete’, window对象触发load事件.
  10. 从此, 以异步响应方式处理用户输入, 网络事件.
越来越多的平台(微信公众平台,新浪微博,简书,百度打赏等)支持打赏功能,付费阅读时代越来越近,特此增加了打赏功能,支持微信打赏和支付宝打赏。坚持原创技术分享,您的支持将鼓励我继续创作!