首页 / 脚本样式 / Ajax / 挣脱浏览器的束缚(3) - 两个连接还不够“并行”
挣脱浏览器的束缚(3) - 两个连接还不够“并行”2010-07-26赵劼在讨论这次的主题之前,我们现在看一下脚本优化的另一个问题,就是“优化难度”。在这里我所说的“优化难度”是指优化一张页面时的修改难度。例如在前一片文章中,使用document.write来引入脚本的话,其“优化难度”会非常的低——没有任何副作用,不用修改其它任何代码。不过它的效果似乎还不太理想,因为仅仅优化了IE下的体验,在FireFox里却没有任何作用。很可惜,我回想了几乎所有的优化方式,再也没有找到优化难度如此低的做法了。对于其它的方式,我们都必须在页面的别处进行修改,优化效果越好,修改量越大。对于这些优化方式,我们就必须编写合适的组件,将一些逻辑封装起来。这样可以在一定程度上方便使用,降低优化难度。比较document.write与defer那么这又何document.write或者defer有什么关系?且听我慢慢道来。<script />的defer属性在标准里的定义是这样的:When set, this boolean attribute provides a hint to the user agent that the script is not going to generate any document content (e.g., no "document.write" in javascript) and thus, the user agent can continue parsing and rendering.我们当时遇到JS无法并行下载的原因就是浏览器认为在脚本中可能会输出HTML内容。defer属性的作用就是告诉浏览器,脚本里不会输出任何信息。果然,当我们在IE里使用defer属性时,脚本没有被阻塞,其效果和document.write一样。不过在FireFox里依旧不行,这样的实现实在让人费解。都说FireFox标准,看来在细节上也不尽然。那么为什么我们在之前使用了document.write而不是defer属性呢?两者效果相同,但是明显使用defer属性更加直观啊。defer属性使用起来的确直观和方便。不过,效果真的相同吗?我们可以通过以下的例子试试看。document.write<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript" language="javascript">
document.write(
"<script type="text/javascript" language="javascript"" +
" src="Scripts.ashx?a"><" + "/script>");
document.write(
"<script type="text/javascript" language="javascript"" +
" src="Scripts.ashx?b"><" + "/script>");
document.write(
"<script type="text/javascript" language="javascript"" +
" src="Scripts.ashx?c"><" + "/script>");
</script>
</head>
<body>
<input type="button" value="Click" />
<script type="text/javascript" language="javascript" src="Scripts.ashx?a">
alert("Hello World");
</script>
</body>
</html>
然后再使用<script defer="defer"></script>的方式引入一下。打开两个页面进行比较就会发现,如果使用document.write的话,在脚本加载完毕之前按钮不会显示,也不会出现提示框;而如果使用defer属性的话,按钮就立即出现了,也会马上出现提示。这可麻烦了。如果页面上的元素过早出现,用户在脚本加载完之前进行操作是否会有问题?如果页面里存在直接执行的脚本(如上例的alert调用),在脚本文件加载完之前是否能够执行?如果上面两个问题的答案有任何一个是肯定的话,那么恭喜您,使用defer属性就会造成错误了。而且这个问题的解决方案实在不太容易找到,这大大增加了“优化难度”。而且更为关键的是,FireFox同样不支持defer属性的效果。这直接导致了defer属性全面落后于使用document.write的优化方式。既然这样,我们为什么要用它?事实上defer属性用的实在不多,这是个非常典型的的“鸡肋”特性。那么,哪里有使用defer属性的应用呢?我想应该是有的吧,虽然我不知道。