网站广告联盟代码速度优化

现在绝大部分广告联盟的广告代码都是使用document.write方式载入到页面中,这种方式很方便,但是可能会阻塞页面剩余内容的加载。
由于广告服务商技术水平参差不齐以及客户端网络的差异,特别在广告位比较多的情况下,有可能导致广告代码引起的用户体验下降。
所以引出本文的优化,其核心思想是重写document.write函数,借鉴了某未知同胞的代码。

1、在全局JS里面增加代码

<script type="text/javascript">
var loadScript = ( function() {
	var adQueue = [], adQueueTmp = [], dw = document.write, dwl = document.writeln;

	function LoadADScript(url, charset, container, init, callback) {
		this.url = url;
		this.charset = charset;
		this.containerObj = ( typeof container == 'string' ? document.getElementById(container) : container);
		this.init = init ||
		function() {
		};

		this.callback = callback ||
		function() {
		};

	}

	LoadADScript.prototype = {
		startLoad : function() {
			var script = document.createElement('script'), _this = this;

			_this.init.apply();

			if(script.readyState) {//IE
				script.onreadystatechange = function() {
					if(script.readyState == "loaded" || script.readyState == "complete") {
						script.onreadystatechange = null;
						_this.startNext();
					}
				};
			} else {//Other
				script.onload = function() {
					_this.startNext();
				};
			}
			document.write = function(ad) {
				ad = ad.replace(/&lt;script.*?src=('|")(.*?)('|").*?&gt;/, function(a0, a1, a2, a3){
						var charsetMatch = a0.match(/charset=('|")(.*?)('|")/);
						var charset = '';
						if(charsetMatch) charset = charsetMatch[2];
						var idd = '_rand_'+Math.random();
						adQueueTmp.unshift({
								url: a2,
								container: idd,
								callback: $.noop,
								charset: charset
						});
						return '<span id="'+idd+'"></span>';
				});
				$(_this.containerObj).append($(ad));
			};
			document.writeln = document.write;

			script.src = _this.url;
			script.type = 'text/javascript';
			if(_this.charset) script.charset = _this.charset;
			document.getElementsByTagName('head')[0].appendChild(script);
		},
		finished : function() {
			document.write = this.dw;			
			document.writeln = this.dwl;
		},
		startNext : function() {
			adQueue.shift();
			$.each(adQueueTmp, function(_, script){
				loadScript.add(script, true);
			});
			adQueueTmp = [];
			this.callback.apply();
			if(adQueue.length &gt; 0) {
				adQueue[0].startLoad();
			} else {
				this.finished();
			}
		}
	};

	return {
		add : function(adObj, insert) {
			if(!adObj)
				return;

			adQueue[insert ? 'unshift' : 'push'](new LoadADScript(adObj.url, adObj.charset, adObj.container, adObj.init, adObj.callback));
			return this;
		},
		execute : function() {
			if(adQueue.length &gt; 0) {
				adQueue[0].startLoad();
			}
		}
	};
}());
</script>

2、在需要显示广告的地方加html占位符,如(id要唯一)

<span id="placeholder"></span>

3、在页面尾部添加对应广告js代码

<script type="text/javascript">
loadScript.add({
	init: function(){
	},	
	url: 'http://e.7clink.com/cpc.php?c=xxxxxxxxxxxxxxxxxxxxxx',	
	container: 'da_200',	
	charset: 'utf-8',	
	callback: $.noop
});
</script>

4、多个广告重复2和3的操作,最后在页面最尾部添加js代码:

<script type="text/javascript">
loadScript.execute();
</script>