1. Advertising code analysis
Many third-party advertising systems use document.write to load advertisements, such as the following javascript advertising link.
The code copy is as follows:
<script type="text/javascript" src="http://gg.5173.com/adpolestar/5173/
;ap=2EBE5681_1BA3_4663_FA3F_E73D2B83FBDC;ct=js;pu=5173;/?"></script>
This javascript request returns a piece of code like this:
The code copy is as follows:
document.write( "<a href='http://gg.5173.com/adpolestar/wayl/;" +
"ad=6FF3F844_33E6_86EE_3B96_D94C1CF1AEC4;ap=2EBE5681_1BA3_4663_FA3F_E73D2B83FBDC;" +
"pu=5173;/?http://www.7bao.com/g/xlsbz/index' target='_blank'><img src='" +
"http://html.5173cdn.com/market/yunyinga/xly132.gif' " +
"border='0' /></a>" );
This kind of loading method that seems a bit 2, but you can't modify it because it's a third-party. In addition, the code has added statistics function. The above javascript ad link will be counted once every time it is requested. The generated code also has the function of click statistics, which means that it must be loaded in this way.
document.write is synchronized during page rendering. You must wait until the javascript code is downloaded and document.write is executed before rendering the following content. If there are many advertisements, it will cause the page to block, especially if several advertisements with larger image sizes are inserted on the first screen of the page. The blocking situation will be quite obvious and serious, which will make users feel that your web page is very slow.
2. Rewrite document.write
In order to avoid blockage, the document.write method cannot be executed during page rendering. You must find a way to make the javascript ad code execute after the DOM tree is ready. However, after the DOM tree is ready, the entire page will be re-rendered, which is not possible. Although document.write is a browser native method, you can also customize a method to overwrite the original method. Before the javascript ad code is loaded, rewrite document.write, wait until it is loaded and executed before changing it back.
3. Delay loading of javascript code
The above key step is to delay loading javascript code. How to implement it? First try to rewrite the type attribute of script, such as setting the type into a custom property "type/cache", but in this way, most browsers (Chrome will not download) will still download this code, but will not execute it. Downloading such a piece of code during page rendering will still block. Rewriting the type of script cannot achieve real delayed loading. At most, it can only load but not execute, and there are compatibility issues.
Put the script tag into the textarea tag and read the textarea content when it needs to be loaded. This way, you can realize the real delay loading of script. This method is thanks to Yu Bo for the BigRender (outside the wall) solution proposed by him.
The code copy is as follows:
<div>
<textarea style="display:none">
<script type="text/javascript" src="http://gg.5173.com/adpolestar/5173/
;ap=2EBE5681_1BA3_4663_FA3F_E73D2B83FBDC;ct=js;pu=5173;/?"></script>
</textarea>
</div>
Delay loading script and rewrite document.write. The following is the code implementation:
The code copy is as follows:
/**
* Rewrite document.write to implement non-blocking loading script
* @param { Dom Object } textarea element
*/
var loadScript = function( elem ){
var url = elem.value.match( /src="([/s/S]*?)"/i )[1],
parent = elem.parentNode,
// Cache native document.write
docWrite = document.write,
// Create a new script to load
script = document.createElement( 'script' ),
head = document.head ||
document.getElementsByTagName( 'head' )[0] ||
document.documentElement;
// Rewrite document.write
document.write = function( text ){
parent.innerHTML = text;
};
script.type = 'text/javascript';
script.src = url;
script.onerror =
script.onload =
script.onreadystatechange = function(e ){
e = e || window.event;
if( !script.readyState ||
/loaded|complete/.test(script.readyState) ||
e === 'error'
){
// Restore native document.write
document.write = docWrite;
head.removeChild( script );
// Uninstall events and disconnect DOM references
// Try to avoid memory leaks
head =
parent =
elem =
script =
script.onerror =
script.onload =
script.onreadystatechange = null;
}
}
// Load script
head.insertBefore( script, head.firstChild );
};
4. Enhanced version of picture delay loading
Can it be further optimized by implementing unblocked lazy loading of javascript ad code? If the ad does not appear on the first screen, can it be used to delay load like the usual delay loading of images? The answer is yes. I expanded the lazy loading plug-in for the image I wrote before, and changed the original image loading method (replace src) to the loadScript method above to achieve it. Of course, just such modifications will still be problematic. If there are multiple pictures and loadScript is carried out at the same time, and document.write is a global method, so it is not guaranteed not to affect B when loading A. They must be loaded one by one, so that B can only be loaded after loading A.
V. Queue Control
In order for javascript ad codes to load in order, a queue is needed to control loading. So the following simple queue control code is also available:
The code copy is as follows:
var loadQueue = [];
// Join the list
var queue = function( data ){
loadQueue.push( data );
if( loadQueue[0] !== 'runing' ){
dequeue();
}
};
// Delist
var dequeue = function(){
var fn = loadQueue.shift();
if( fn === 'runing' ){
fn = loadQueue.shift();
}
if( fn ){
loadQueue.unshift( 'runing' );
fn();
}
};
Please refer to the comparison article for image delay loader: http://www.VeVB.COM/article/50685.htm