我们在MDN
官方上面看到了script
具备两个有意思的属性:async
,defer
,其中defer
兼容性还不如async
,IE10
以上都支持async
,defer
,Opera15
以上都支持async
,defer
,Opera15
好像现在暂时不支持。
我们用HTML
深入(一)的TimeLine
来试一试,也是HTML
深入(一)的代码。
当我们不用这两个属性会是怎样的呢?
我们在深入(一)就讲过,蓝色是HTML
解析,黄色是javascript
,那么图中的四个红框框框起来的就是我们的test1.js
,test2.js
,test3.js
,test4.js
。他们分别按照顺序运行完。
所以在我们只是用script
没有用defer
和async
的时候,HTML
从上至下渲染时是需要等待第一个js
加载执行完后,再运行另外一个,在运行js
的时候,HTML
渲染停止,不做任何事情。主要的执行顺序就是,如果finish loading
完了,就会立马执行js
脚本,这个执行完后呢,又接着往下构造DOM
,遇到js
又这么执行,中间不能做其他事情。
defer
性能优化策略
上面为测试的代码
我们发现所有的js
文件都进行了finish loading
但是却没有编译运行,连loaded
事件都被延迟了。
然后我们移动到第一次调用onreadystatechange
的地方,发现了,所有的js
文件都在这里编译执行了,同时load
事件也是在编译执行后触发了,(这里我们就明白了原来load
事件的触发是在js
文件运行完成之后),这个过程发生在DOMContentLoaded
事件之前。
然后呢我们发现即便是将js
执行的时间推迟到了第一次onreadystatechange
后,js
文件的执行好像也是顺序的。
为了验证这一点,我们交换一下Script
引用文件的顺序,结果就变成如下:
所以结论是正确的,defer
会将我们js
推后,并且还是按照在HTML
文件中script
的顺序进行执行,当然这个属性起作用必须是用src
来引用的,没有src
一切无效。
defer
总结
这里我们就可以明白了defer
是干什么用的,它只是将我们js
的执行过程退后而已,这样有什么好处呢,就是可以提高性能,因为当我们没有defer
的时候,我们的DOM
构造的时候会阻塞,只有当js
执行完了才能往下走,导致HTML
后续的工作被停止,而defer
则将js
执行的工作放到了所以DOM
节点构造完成之后,这就大大的节省了时间。
async
性能优化策略
我们将代码修改一下,然后重新刷新页面
我们发现了test1.js
先执行,而其它的脚本文件都老后了。
同时执行完test1.js
后,还进行了一段时间的DOM
构建,如此可见,它的异步性是,对js
脚本异步处理,但是只要接受读取这个js
脚本后就立马执行,和defer
不同的就是它不会等到DOM
构建完成之后才执行。
async
总结
async
和defer
一样都是异步处理的,而async
的异步处理只要接受到了js
文件,并且加载完毕后就立即执行。
注意
在脚本中最好不要用document.write
,因为他会清空网页,然后进行重写