拉取HTML页面(e.g.index.html)
开始解析HTML
解析到标签之后准备获取script文件.
浏览器获取script文件。同时,html解析中断并且
阻断
页面上其他html的解析。一段时间后,script下载完成并且
执行
。继续解析HTML文档的其他部分(解析script之后的html代码)
第4步导致了不好的用户体验,直到script文件全部下载完成之前HTML都不能得到解析。
为什么会发生阻断事件?
任何script代码都能改变HTML的结构,通过这种方式或者其他方式。这就导致了HTML解析必须等待script全部被下载和执行完,HTML才能解析script标签之后余下的部分。
然而,大部分的Javascript开发者在加载文档过程中,不会通过script操作HTML的DOM结构。然而,他们必须等到script全部加载结束,才能看到页面。举个例子:
Javascript:
因为你的浏览器在下载并执行完my-script.js标签之前,并不知道my-script.js这个文件不会去修改DOM结构,导致HTML停止解析(在script下载并执行完之前)
之前推荐的方法(已过时):
之前解决这个问题的方法是把标签放到标签之后,这确保了解析到</body>之前都不会被script终端。
这个方法是有问题的:浏览器在整个文档解析完成之前都不能下载script文件,如果文档很大的话,解析完HTML,用户依然要等待script文件下载并执行完成之后,才能操作这个网站。(主要是串行,先解析HTML完,再下载并执行script,速度肯定没有并行块,那么怎么并行呢?大家假设能在解析HTML一开始,就开始下载script,并且不阻断HTML的解析,是不是就并行了呢)如果你的网站在2秒之内没有响应,用户就会跑掉;
现在推荐的解决方案:
现在浏览器script标签支持和属性.应用这些属性当script被下载时,浏览器更安全而且可以并行下载(下载script并不阻断HTML解析)。
async
async标记的Script异步执行下载,并执行。这意味着script下载时并不阻塞HTML的解析,并且下载结束script马上执行。异步意味着,上述代码script2可能比script1先下载完并执行完。
根据
http://caniuse.com/#feat=script-async
,90%的浏览器支持async属性.defer
defer标签的script顺序执行。这种方式也不会阻断浏览器解析HTML。
跟async不同,deferscripts在整个文档里的script都被下载完才
顺序执行
。根据
http://caniuse.com/#feat=script-defer
,90%的浏览器支持这个属性.92%至少部分支持此属性。注意:在IE<=9浏览器应用defer属性可能会导致script不会顺序执行。如果你想让低版本IE支持此属性,请看
this
结论
应用or这两个属性,拥抱未来。
原答案来自万能的:
stackoverflow