博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动态装载外部JavaScript脚本文件
阅读量:5977 次
发布时间:2019-06-20

本文共 2613 字,大约阅读时间需要 8 分钟。

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

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

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

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

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

 

具体的实现方法可以参考下面的代码():

 

[javascript]
 
  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.   
  8.     for (var i=0; i<length; i++) {  
  9.         script = document.createElement("script");  
  10.         script.async = true;  
  11.         script.type = "text/javascript";  
  12.         script.src = scripts[i];  
  13.   
  14.         script.onload = function () {  
  15.             loadedScripts++;  
  16.   
  17.             if (loadedScripts === length) {  
  18.                 loadCallback();  
  19.             }  
  20.         };  
  21.   
  22.         script.onreadystatechange = function () {  
  23.             if (script.readyState === "complete") {  
  24.                 loadedScripts++;  
  25.   
  26.                 if (loadedScripts === length) {  
  27.                     loadCallback();  
  28.                 }  
  29.             }  
  30.         };  
  31.   
  32.         parentNode.insertBefore(script, first);  
  33.     }  
  34. };  

调用举例:

[javascript]
 
  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非阻塞装载的一种方法,而列举了许多其他的方案:

 

  • 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.

 

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

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

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

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

转载地址:http://pksox.baihongyu.com/

你可能感兴趣的文章
设计模式--模板方法(Template Method)
查看>>
引入CSS的方式有哪些?link和@import的有何区别应如何选择【转载】
查看>>
MariaDB 和 MySQL 性能测试比较
查看>>
Restful Web Service初识
查看>>
This用法和闭包
查看>>
JSP页面获取系统时间
查看>>
L-1-19 Linux之RAID&分区&文件系统命令
查看>>
stat查找权限以数字形式显示
查看>>
源码编译安装httpd2.4.9
查看>>
linux系统优化
查看>>
在使用 Windows Update 检查更新时,系统没有提供下载 Windows 7 SP1 的选项
查看>>
在Struts + Spring + Hibernate的组合框架模式中,三者各自的特点都是什么
查看>>
Windows 2012 R2 DataCenter服务器DNS无法打开AD, DNS错误代码4000 4007 4013
查看>>
java基础数据类型char
查看>>
打印 PE导入导出表
查看>>
miniWindbg 功能
查看>>
五、判断银行卡号的正则
查看>>
mysql基于mysqlslap的压力测试
查看>>
zencart中query_factory.php中连接mysql次数
查看>>
fail2ban 保护linux安全(转载)已用于生产环境
查看>>