用script的defer属性加快载入页面速度

标签:HTML, JavaScript

在HTML 4的时代,IE为script元素独创了defer属性,这使并行加载和延迟运行变得简单,但却不符合W3C规范。
而今HTML 5也为script元素新增了defer和async这2个属性,于是有必要再研究一下。

首先说说IE的defer,它对用户代理提供一个暗示:脚本不产生任何文档内容(比如没有document.write),这样,用户代理会继续解析并渲染文档。当文档解析完毕,脚本也可用时,才运行脚本。“标准”的写法是defer="defer",但IE并不关心这个值,只要有这个属性即可。
接着是HTML 5,它的defer和IE的很相似,只是必须有src属性(即必须用于载入外部脚本文件);而async则会并行加载,并在可用时立即执行,同样也必须有src属性。它们的值是一个bool,即true或false。

下面来测试下defer在IE 6、Firefox 3.5和Chrome 4中的表现:
<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="gbk"/>
		<title>defer测试</title>
		<style>
			.ui-dialog-titlebar {background: #9cf}
			#result {display: none; background: #eee}
		</style>
		<script>var t1 = new Date();</script>
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" defer="true"></script>
		<script>var t2 = new Date();</script>
		<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" defer="true"></script>
		<script>var t3 = new Date();</script>
		<script>
			function f() {
				var t4 = new Date();
				document.getElementById('s1').innerHTML = t2 - t1;
				document.getElementById('s2').innerHTML = t3 - t1;
				document.getElementById('s3').innerHTML = t4 - t1;
				document.getElementById('s4').innerHTML = typeof($) == 'function' ? "是" : "否";
				document.getElementById('s5').innerHTML = typeof($.ui) == 'object' ? "是" : "否";
				try {
					$('#result').dialog();
				} catch (e) {
					alert('defer测试失败');
				}
			}
		</script>
	</head>
	<body onload="f();">
		<p>等待jQuery载入时间:<span id="s1"></span></p>
		<p>等待jQuery UI载入时间:<span id="s2"></span></p>
		<p>等待脚本执行时间:<span id="s3"></span></p>
		<p>jQuery是否载入:<span id="s4"></span></p>
		<p>jQuery UI是否载入:<span id="s5"></span></p>
		<div id="result" title="测试结果">defer测试通过</div>
	</body>
</html>
IE 6:
等待jQuery载入时间:16
等待jQuery UI载入时间:16
等待脚本执行时间:969
jQuery是否载入:是
jQuery UI是否载入:是
Firefox 3.5:
等待jQuery载入时间:9
等待jQuery UI载入时间:16
等待脚本执行时间:790
jQuery是否载入:是
jQuery UI是否载入:是
Chrome 4:
等待jQuery载入时间:457
等待jQuery UI载入时间:845
等待脚本执行时间:852
jQuery是否载入:是
jQuery UI是否载入:是
可以看到,使用defer让IE 6和Firefox 3.5早了将近1秒的时间来渲染文档的剩余部分,而Chrome 4则并不支持。
万幸的是,这种技术并没有带来太大的副作用,至少这2个库都可以成功载入和使用了,不过测试时用掉了一个宝贵的onload属性。

至于async属性,我测试的结果是都不支持,所以就不贴代码了。

0条评论 你不来一发么↓

    想说点什么呢?