首頁 > web前端 > js教程 > 主體

用js的document.write輸出的廣告無阻塞載入的方法_javascript技巧

WBOY
發布: 2016-05-16 16:46:12
原創
1291 人瀏覽過

一、廣告代碼分析

許多第三方的廣告系統都是使用document.write載入廣告,如下面的一個javascript的廣告連結。

複製程式碼 程式碼如下:


這個javascript請求返回的是這樣的一段代碼:

複製代碼 代碼如下:
這種看似有點二的載入方式,但你卻沒辦法改造它,因為它本身就是第三方的。而且程式碼都加入了統計的功能,上面的javascript的廣告連結每請求一次都會統計一次,產生的程式碼也有點擊統計的功能,也就是說必須以這種方式來進行載入。

document.write是在頁面渲染的時候同步進行的,必須要等javascript程式碼下載好並且document.write執行完後才接著渲染後面的內容,如果廣告比較多的話,就會導致頁面阻塞,尤其是在頁面的首屏插好幾個圖片尺寸比較大的這種廣告,那麼阻塞情況就相當明顯和嚴重,會讓用戶覺得你這個網頁很慢。

用js的document.write輸出的廣告無阻塞載入的方法_javascript技巧

二、重寫document.write

為了避免被阻擋,就不能讓document.write方法在頁面渲染的時候執行,必須想辦法讓javascript的廣告程式碼在DOM樹就緒(DOM ready)之後才執行,但是在DOM樹就緒後執行document. write會重新渲染整個頁面,這樣也是不行的。 document.write雖然是瀏覽器原生的方法,但也可以自訂一個方法來覆寫原來的方法。在javascript廣告程式碼載入之前,重寫document.write,等載入並執行完再改回來。

用js的document.write輸出的廣告無阻塞載入的方法_javascript技巧

三、延遲載入javascript程式碼

上面比較關鍵的一步,延遲載入javascript程式碼,要如何實現呢?先嘗試透過改寫script的type屬性,例如將type設定成一個自訂的屬性”type/cache”,但這樣大部分瀏覽器(Chrome不會下載)仍然會下載這段程式碼,但不會執行,在頁面渲染的時候下載這麼一段程式碼仍然會阻塞,透過改寫script的type並不能實現真正的延遲加載,最多能實現只加載不執行,而且還存在兼容問題。

將script標籤放到textarea標籤中,等需要載入的時候再讀取textarea的內容,這樣可以實現真正的延遲載入script,這個方法要感謝玉伯提出的BigRender(牆外)方案。

複製程式碼 程式碼如下:






延遲載入script並重寫document.write,以下是程式碼實作:

複製程式碼 程式碼如下:

/**
 * 重寫document.write實作無阻塞載入script
 * @param { Dom Object } textarea元素
 */
var loadScript = function( elem ){
 var url = elem.value.match( /src="([sS]*?)"/ i )[1],
  parent = elem.parentNode,
  // 快取複製的document.write
  docWrite = document.write, 
  = document.createElement( 'script' ),
  head = document.head ||
   document.getElementsByTagName( 'head' )[0] ||
|| /重寫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 === '錯誤'
  ){

   // 恢復原來的document.write
   document.write = docWrite;

   head.removeChild( script );

   head =    
   parent =
   elem =
   script =
  }
 }

 // 載入腳本
 head.insertBefore( script, head.firstChild );
};


四、圖片延遲載入的增強版


實現了無阻塞式的延遲載入javascript廣告,能否進一步優化?如果廣告代碼沒有在首屏出現,能否像通常的圖片的延遲加載一樣來進行延遲加載?答案是肯定的。對我來說寫圖片延遲加載的小插件進行擴展,將的圖片加載方式(替換src)改成上面的loadScript方式加載就可以實現了。當然,這樣的修改還是原來會有問題的。如果有多個圖片,而loadScript是同時進行的,而document.write又是全域的方法,保證不准在加載A的時候不影響到B,必須讓它們按順序加載,加載完成A之後才能加載B 。

五、隊列控制

為了讓javascript廣告程式碼依序載入就需要一個佇列來控制載入。於是又有了下面一個簡單的隊列控制代碼:

複製代碼

代碼如下:


};
// 出列 
var dequeue = function(){
 var fn = loadQueue.shift(); ( fn === 'runing' ){
  fn = loadQueue.shift();
 }

 if( fn ){
  loadQueue.unshift( 'runing' ){
  loadQueue.unshift( 'runing');
  fn();
 }
};



圖片延遲載入器請參考比文:
http://www.jb51.net/article/ 50685.htm
 
相關標籤:
js
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板