动态装载外部JavaScript脚本文件

当我们请求一个URL地址时,浏览器会从远程服务器装载各种所需的资源,如JavaScript、CSS、图片等。而在加载JavaScript时,常常会发生下面这种情况:

也就是说,当浏览器碰到Script标签时,会下载整个js文件,同时不会下载其它资源,包括其它的js文件。不过这句话也是“含水分的”,水分到底多大,我也不知道,具体得看我们所使用的浏览器种类以及对应的版本号。下面是IE8的情况,它会同时下载多个js文件以及CSS文件,而图片等内容则会被阻塞,这点与之前的认识稍有不同,IE8多多少少引入了一点点“并发”。

不管怎样,由于采用标签形式所定义的js文件下载会造成整个下载阻塞,所以很多人会把Script标签写在</body>之前,或者是采用动态脚本装载的方式以加快页面显示。其具体例子可以从下面图中看到:

把Script标签写在body标签前来提早显示整个页面,这个是比较容易理解的;而动态脚本装载,是利用js动态创建Script的DOM对象,然后把这个DOM对象添加到当前文档中,从而实现js文件装载,而这种装载的方式与标签所实现的装载方式不同之处就在于不会形成阻塞。

上述所说内容以及图片资源来自以下两篇文章。

http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/

http://www.webdigi.co.uk/blog/2009/avoid-javascript-blocking-content-download-on-your-website-during-page-load/

具体的实现方法可以参考下面的代码(http://stackoverflow.com/questions/2803305/javascript-how-to-download-js-asynchronously):

[javascript] view plaincopy

  1. var require = function (scripts, loadCallback) {
  2. var length        = scripts.length;
  3. var first         = document.getElementsByTagName("script")[0];
  4. var parentNode    = first.parentNode;
  5. var loadedScripts = 0;
  6. var script;
  7. for (var i=0; i<length; i++) {
  8. script = document.createElement("script");
  9. script.async = true;
  10. script.type = "text/javascript";
  11. script.src = scripts[i];
  12. script.onload = function () {
  13. loadedScripts++;
  14. if (loadedScripts === length) {
  15. loadCallback();
  16. }
  17. };
  18. script.onreadystatechange = function () {
  19. if (script.readyState === "complete") {
  20. loadedScripts++;
  21. if (loadedScripts === length) {
  22. loadCallback();
  23. }
  24. }
  25. };
  26. parentNode.insertBefore(script, first);
  27. }
  28. };

调用举例:

[javascript] view plaincopy

  1. require([
  2. "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
  3. "http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js",
  4. "http://ajax.googleapis.com/ajax/libs/yui/2.7.0/build/yuiloader/yuiloader-min.js"
  5. ], function () {
  6. console.log(jQuery);
  7. console.log($);
  8. console.log(YAHOO);
  9. });

上面的代码只是外部JavaScript非阻塞装载的一种方法,而http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/列举了许多其他的方案:

  • XHR Eval – Download the script via XHR and eval() the responseText.
  • XHR Injection – Download the script via XHR and inject it into the page by creating a script element and setting its text property to the responseText.
  • Script in Iframe – Wrap your script in an HTML page and download it as an iframe.
  • Script DOM Element – Create a script element and set its src property to the script’s URL.
  • Script Defer – Add the script tag’s defer attribute. This used to only work in IE, but is now in Firefox 3.1.
  • document.write Script Tag – Write the <script src=""> HTML into the page using document.write. This only loads script without blocking in IE.

虽然这些方案都可以实现无阻塞下载,但还有一点要记住,对于一个域来说浏览器所能打开的连接数是有限的,从下面链接可以找出一些相关的数据:

http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/

对于同一个域来说,连接个数是有限的,不过我们可以通过让一个页面引用多个域的资源以达到扩大连接数的目的。所以有时会发现有的Web应用将动态程序和静态的资源分到不同的应用当中。另外还有一种主动的方法,就是客户机主动设置浏览器的最大连接数:http://support.microsoft.com/?kbid=282402。对于IE6和7来说,默认的最大连接数是2,在做聊天室,使用“长轮询”作为解决方案时一定要多考虑考虑。

最后给出的几篇文章,是同一个作者不同时期的文章,其内容全是关于动态装载的,可以作为参考:

技术总是在更新换代,现在我们关注的问题可能几年之后就会变成老皇历了。因为新的HTML5标准中,可以在script(http://dev.w3.org/html5/spec/Overview.html#the-script-element)上使用defer和async属性了,如果再加上浏览器本身的技术与概念的进步和“摩尔定律”的鼓吹,三五年差不多够了。

时间: 2024-08-04 20:36:44

动态装载外部JavaScript脚本文件的相关文章

动态引用外部的Javascript脚本文件[转]

你可以参考下面方法,进行动态为网页引用外部的Javascript脚本文件.代码写在Page_Init方法内. VB.NET: 下图是运行时,查看HTML的源代码: C#:

LABjs学习(一)之无阻塞动态并行加载脚本文件以及管理执行顺序

什么是LABjs LABjs是一个动态的脚本加载器,LABjs的定义特性是能够在浏览器允许的范围内以最快的速度并行加载所有JavaScript文件,但是如果文件之间存在依赖关系,则可以选择确保正确的执行顺序. 总计来说就是:动态并行加载脚本文件以及管理加载脚本文件的执行顺序 使用方法 $LAB对象替代了<script>标签,然后.script()方法表示加载Javascript文件,不带参数的.wait()方法表示立即运行刚才加载的Javascript文件,带参数的.wait()方法也是立即运

获取当前Javascript脚本文件的路径

获取当前Javascript脚本文件的路径 获取当前Javascript脚本文件的路径,在特定场景下可能需要,比如写模块加载器,或者进行日志记录.并没有统一的方法适用于所有浏览器,本文分几种情况进行说明. (1). 标准做法: document.currentScript 对象的src属性 适用于Firefox 4+, Chrome 29+, Opera 16+, Safari 8+. var src = document.currentScript.src; (2). 从Error对象的sta

MySQL执行外部sql脚本文件命令报错:unknown command &#39;\&#39;

由于编码不一致导致的 虽然大部分导出是没有问题的 但是数据表中存储包含一些脚本(富文本内容)会出现该问题,强制指定编码即可解决. mysql导入时指定编码: mysql -u root -p --default-character-set=utf8 或者在导出时后显式指定编码就不存在这个问题了: mysqldump -uroot -p --default-character-set=utf8 mydb > E://xxxx.sql MySQL执行外部sql脚本文件命令报错:unknown com

使用jQuery动态加载js脚本文件的方法

动态加载Javascript是一项非常强大且有用的技术.这方面的主题在网上已经讨论了不少,我也经常会在一些个人项目上使用RequireJS和Dojo加载js 它们很强大,但有时候也会得不偿失.如果你使用的是jQuery,它里面有一个内置的方法可以用来加载单个js文件.当你需要延迟加载一些js插件或其它类型的文件时,可以使用这个方法.下面就介绍一下如何使用它! 一.jQuery getScript()方法加载JavaScript jQuery内置了一个方法可以加载单一的js文件:当加载完成后你可以

MySQL执行外部sql脚本文件的命令

进入mysql的控制台后,使用source命令执行 Mysql>source [sql脚本文件的路径全名] 或 Mysql>\. [sql脚本文件的路径全名], 示例:source d:\test\ss.sql 或者 \. d:\test\ss.sql

jQuery动态加载js脚本文件

jQuery getScript()方法加载JavaScript jQuery.getScript("/path/to/myscript.js", function(data, status, jqxhr) { /* 做一些加载完成后需要执行的事情 */ }); jQuery.getScript("/path/to/myscript.js") .done(function() { /* 耶,没有问题,这里可以干点什么 */ }) .fail(function() {

浏览器环境下JavaScript脚本加载与执行探析之代码执行顺序

本文主要基于向HTML页面引入JavaScript的几种方式,分析HTML中JavaScript脚本的执行顺序问题 1. 关于JavaScript脚本执行的阻塞性 JavaScript在浏览器中被解析和执行时具有阻塞的特性,也就是说,当JavaScript代码执行时,页面的解析.渲染以及其他资源的下载都要停下来等待脚本执行完毕①.这一点是没有争议的,并且在所有浏览器中的行为都是一致的,原因也不难理解:浏览器需要一个稳定的DOM结构,而JavaScript可能会修改DOM(改变DOM结构或修改某个

使用js加载器动态加载外部Javascript文件

今天在网上找到了一个可以动态加载js文件的js加载器,具体代码如下: JsLoader.js 1 var MiniSite=new Object(); 2 /** 3 * 判断浏览器 4 */ 5 MiniSite.Browser={ 6 ie:/msie/.test(window.navigator.userAgent.toLowerCase()), 7 moz:/gecko/.test(window.navigator.userAgent.toLowerCase()), 8 opera:/o