最近Firefox 4和Firebug 1.7终于正式发布了,大家都积极上手体验了一番,很快有很多关于FF4的研究文章,我最近看了一篇专题文章,主要介绍了FF4与前期版本中js脚本执行方式的差异;当我们想要查看页面中的js脚本执行详情时,我们都会借助于FF的常用插件工具Firebug的控制台,我们能通过瀑布图很清晰地分析js脚本的执行情况。
那么接下来写的这篇博文中会以Firebug控制台的瀑布图截图为例帮助大家更好地了解FF4中对于js脚本是如何执行的?有了哪些变化?(注:本文中以FF3.6版本为参考进行对比)
“关于旧版本的Firefox去执行非异步,非延迟脚本的时候,皆是按照先后顺序依次运行的!”
接下来,具体介绍下Firefox 4中脚本执行方式的改变,我们会通过三种情况并借助于Firebug来一步一步对比分析。首先我们先定义三个基本函数,在下面的例子中会应用到:
- function addExternalScript(url)
- {
- var script = document.createElement("script");
- script.src = url;
- document.getElementsByTagName("head")[0].appendChild(script);
- }
- function addInlineScript(source)
- {
- var script = document.createElement("script");
- script.innerHTML = source;
- document.getElementsByTagName("head")[0].appendChild(script);
- }
1.addExternalScript 这个函数是用来创建一个script标签然后动态插入到文档中,最后将外部资源地址URL赋值给这个script标签;
2.addInlineScript 这个函数也很简单,顾名思义,从字面也可以容易理解了,就是同上个函数的原理,只不过赋给script的值是内嵌的资源;
那么对于上面两个函数所引用的外部函数具体代码非常简单,只做一件事,记录而已:
- console.log(<here-is-name-of-the-script-file>);
现在已经万事俱备了,剩下的就看Firebug这位“大神”的威力了,仔细观察对比控制台。
Example #1
“在内联脚本中若存在请求外部资源并未完全获取到之前,内联脚本的执行方式大不同”
看下面代码示例:
- <script type="text/javascript">
- console.log("start");
- addExternalScript("script1.js");
- addInlineScript("console.log('inline script')");
- console.log("end");
- </script>
以上代码段原理很简单,就是在文档中插入一个外部脚本并在它进行下载过程中页面又即时添加了另一个内嵌脚本。
这段代码如果在Firebug中的NET(网络)面板中查看请求时,FF3.6 与 FF4两个版本一致。但是在控制台面板你就会发现差异了,如下图:
总结:通过上面实例对比,可以看出在FF4中是内联的脚本都会同步执行的,但是在FF3.6中则不是的。
Example #2
“在解析内联式脚本与外链脚本资源时,阻塞问题的也不相同。”
还是贴代码:
- <script type="text/javascript">
- console.log("start");
- addExternalScript("script1.js");
- console.log("end");
- </script>
- <script type="text/javascript" src="script2.js"></script>
以上代码实现的是在页面原始存在的script元素前动态添加一个脚本。
Example #3
“内嵌方式将非异步,非延迟的外部脚本资源插入文档时的执行顺序也是存在不同的。”
继续代码:
- <script type="text/javascript">
- console.log("start");
- addExternalScript("script1.js");
- addExternalScript("script2.js");
- addExternalScript("script3.js");
- console.log("end");
- </script>
代码实现非常清晰,就是按照顺序在document文档中插入三个script元素。
对比如下图所示:
总结:在FF3.6中脚本同插入页面中的顺序一样进行加载,看上去挺不错的,但是它们也是按照同样的顺序去执行的!那么换句话说,在script1完成后执行完script2,然而期间几乎浪费了1.5秒时间(因为这期间JS引擎其实什么也没做)。对于script3亦然如此。然后在FF4中就完全不是这么“迂腐”了,总而言之,就是根据谁加载的快谁就先执行,亦即每个脚本一旦加载完成立即执行。
通过上面的三个例子对FF4中脚本执行方式所表现出的不同进行了简单地分析,我想对于我们理解FF4是如何进行解析的应该很有帮助,同时感觉随着版本的升级JS引擎也越来越智能化了!
声明:本篇文章大部分内容均为翻译,有不准确或欠缺的地方还请大家帮忙指出。