script标签属性之:剖析async(异步加载js)
HTML5中的script属性
1、移除了language属性,改type为可选。
2、新增async属性,定义脚本是否异步执行,取值true或false。
加入这属性就可以在head标签内插入script,脚本与文档同时下载,脚本、文档同时执行。
async的作用(区分于defer):
1 async 属性为 true,则脚本会相对于文档的其余部分异步执行,这样脚本会可以在页面继续解析的过程中来执行。
2 async 属性为 false,而 defer 属性为 true,则脚本会在页面完成解析时得到执行。
3 async 和 defer 属性均为 false,那么脚本会立即执行,页面会在脚本执行完毕继续解析。
回顾:
HTML4.01为script标签定义了5个属性:
charset 可选。指定src引入代码的字符集。
defer 可选。延迟脚本执行,相当于把script标签放入body的底部。除了IE和新版firefox以外,其他浏览器不支持。
language 已废弃。
src 可选。指定引入外部代码文件,不限制后缀名。
type 必选。指定脚本的内容类型(mime类型)。缺省时默认为text/javascript。
javascript的同步和异步
1、同步加载
我们平时最常使用的就是这种同步加载形式:
<script src="**.js"></script>
同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止了后续的解析,因此停止了后续的文件加载(如图像)、渲染、代码执行。
js 之所以要同步执行,是因为 js 中可能有输出 document 内容、修改dom、重定向等行为,所以默认同步执行才是安全的。
把<script>放在页面末尾</body>之前,这样尽可能减少这种阻塞行为,而先让页面展示出来。
简单说:加载的网络 timeline 是瀑布模型,而异步加载的 timeline 是并发模型。
2、常见异步加载(Script DOM Element)
(function() { var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = 'http://yourdomain.com/script.js'; var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(s, x); })();
此方法被称为 Script DOM Element 法,不要求 js 同源。将js代码包裹在匿名函数中并立即执行的方式是为了保护变量名泄露到外部可见。
但是,这种加载方式在加载执行完之前会阻止onload事件的触发,而现在很多页面的代码都在onload时还要执行额外的渲染工作等,所以还是会阻塞部分页面的初始化处理。
异步加载又叫非阻塞,浏览器在下载执行 js 同时,还会继续进行后续页面的处理。
这种方法是在页面中<script>标签内,用 js 创建一个 script 元素并插入到 document 中。这样就做到了非阻塞的下载 js 代码。
3、延迟加载(lazy loading)
有些 js 代码并不是页面初始化的时候就立刻需要的,而稍后的某些情况才需要的。延迟加载就是一开始并不加载这些暂时不用的js,而是在需要的时候或稍后再通过js 的控制来异步加载。也就是将js切分成许多模块,页面初始化时只加载需要立即执行的js,然后其它js的加载延迟到第一次需要用到的时候再加载。
特别是页面有大量不同的模块组成,很多可能暂时不用或根本就没用到。
就像图片的延迟加载,在图片出现在可视区域内时(在滚动条下拉)才加载显示图片。
参考文章:
http://zj86.info/Front-end-Development/HTML5-in-the-async-property-of-asynchronous-script-loading-JS