相信各位都知道所有浏览器在下载JS的时候,会阻止一切其他活动,比如其他资源的下载,内容的呈现等等。至到JS下载、解析、执行完毕后才开始继续并行下载其他资源并呈现内容。

首先我来解释一下原因

先说说浏览器构造页面的原理

当浏览器从服务器接收到了HTML文档,并把HTML在内存中转换成DOM树,在转换的过程中如果发现某个节点(node)上引用了CSS或者 IMAGE,就会再发1个request去请求CSS或image,然后继续执行下面的转换,而不需要等待request的返回,当request返回 后,只需要把返回的内容放入到DOM树中对应的位置就OK。但当引用了JS的时候,浏览器发送1个js request就会一直等待该request的返回。

那这个构造原理和JS的加载有什么相关的呢?

因为浏览器需要1个稳 定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,比如使用document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现。

下图是访问blogjava首页的时间瀑布图,可以看出来开始的2个image都是并行下载的,而后面的2个JS都是阻塞下载的(1个1个下载)。

回归正题,通常一些大流量的网站都会在页面中嵌入广告JS,通过这些JS来进行网赚

但是很多时候这些JS反而成为妨碍网站加载的阻碍

这时候就要用到异步加载了

主要的步骤:

  • 创建一个scriptDOM节点;
  • 对其的type属性赋值为text/javascript;
  • 再指定它的src属性为要加载的js文件URL;
  • 把这个DOM节点加入到页面中。

方法1:

这个方法有BUG,就是当加载的js文件含有document.write语句的时候,IE会无法正常加载,而FF则会显示空白的网页,所以说这个方法只是拿出来给大家看看,不建议使用

function include_js(path,reload)   
{   
var scripts = document.getElementsByTagName(“script”);   
if (!reload)   
for (var i=0;i<scripts.length;i++)   
if (scripts[i].src && scripts[i].src.toLowerCase() == path.toLowerCase() ) return;   
var sobj = document.createElement(‘script’);   
sobj.type = “text/javascript”;   
sobj.src = path;   
var headobj = document.getElementsByTagName(‘head’)[0];   
headobj.appendChild(sobj);   
}

这种BUG当然会有解决的办法,就是重写document.write

首先是在需要write的区域加上

之后在上面的代码中的include_js之前加上一句

document.write = function (s)   
{   
document.getElementById(‘jsdiv’).innerHTML+=s;   
return false;   
}  

这样JS就能正常的异步加载了

转自:【JS】异步加载广告JS – 西德欧的实验室.

- EOF -