高效能JavaScript:載入和執行

來源:互聯網
上載者:User

       在步入正題之前為大家介紹一本很好的書《高效能JavaScript》大家不妨看一下,在本文中我為大家分享我看這本書的一些收穫。

阻塞特性
       JS 有個很無語的阻塞特性,就是當瀏覽器在執行JS 代碼時,不能同時做其他任何事情,無論其代碼是內嵌的還是外部的。

指令碼位置:
       瀏覽器在碰到一個引入外部JS 檔案的<script>標籤時會停下所有工作來下載並解析執行它,在這個過程中,頁面渲染和使用者互動完全被阻塞了,為了避免頁面載入時的停頓甚至空白頁的出現,JS 指令碼應盡量放置在頁面底部,這點很重要:

 
  1. <html>  
  2. <head>  
  3. <title>無標題文檔</title>  
  4. <link rel="stylesheet" type="text/css" href="styles.css" />  
  5. </head>  
  6. <body>  
  7. <p>頁面的內容。。。</p>  
  8. <!-- 推薦的位置,頁面底部: -->  
  9. <script type="text/javascript" src="file1.js"></script>  
  10. <script type="text/javascript" src="file2.js"></script>  
  11. <script type="text/javascript" src="file3.js"></script>  
  12. </body>  
  13. </html> 

組織指令碼:
       為了改善上面的阻塞情況,應儘可能的減少頁面中<script>標籤的出現次數,這同時也是考慮到HTTP 要求會帶來額外的效能開銷,也就是說應減少頁面中外鏈指令碼的數量。

你可以手動合并你的多個JS 檔案,也可採用類似Yahoo! combo handler 這樣的即時線上服務來實現,例如下面的這個<script>標籤實際上便載入了3個JS 檔案:

 
  1. <html>    
  2. <head>    
  3. <title>無標題文檔</title>    
  4. <link rel="stylesheet" type="text/css" href="styles.css" />    
  5. </head>    
  6. <body>      
  7. <p>頁面的內容。。。</p>      
  8. <!-- 推薦的位置,頁面底部: -->    
  9. <script type="text/javascript" src="http://yui.yahooapis.com/combo?file1.js&file2.js&file3.js"></script>    
  10. </body>    
  11. </html> 

無阻塞的指令碼:
為了阻塞狀況,這裡提供了幾個實現並行下載JS 指令碼的方案。

1. 延遲的指令碼

HTML4 為<script>標籤定義了一個defer 屬性,它能使這段代碼順延強制,然而該屬性只有IE4+ 和Firefox 3.5+ 支援。聲明了defer 屬性的<script>會在DOM載入完成,window.onload 事件觸發前被解析執行:

 
  1. <script type="text/javascript" src="file1.js" defer></script> 

2. 動態指令碼元素
       這是最通用的解決方案,通過DOM 動態地建立<script>元素並插入到文檔中,檔案在該元素被添加到頁面時開始下載,這樣 無論在何時啟動下載,檔案的下載和執行過程不會阻塞頁面其他進程。

不過要注意使用這種方式載入的代碼會立刻執行,這樣需清楚的瞭解各檔案的作用以及合理的執行順序,此時跟蹤並確保指令碼下載完成並準備就緒是很有必要的,非IE瀏覽器會在<script>元素接收完成時觸發一個load 事件,而IE 下則會觸發一個readystatechange 事件並通過readyState 屬性加以判斷便可。以下是相容地動態載入一個JS 指令碼的函數:了:

 
  1. function load_script(url, callback)   
  2. {      var script = document.createElement("script");        
  3.        script.type = "text/javascript";  
  4.        if (script.readyState)   
  5.        {  //IE   
  6.          script.onreadystatechange = functio()
  7. {          
  8.  if (script.readyState == "loaded"  script.readyState == "complete") 
  9. {
  10.                 script.onreadystatechange = null;
  11.                 callback();
  12.              }
  13.            }
  14.       } 
  15. else
  16. { //others
  17.         script.onload = function(){ 
  18.              callback(); }
  19.       }
  20.       script.src = url;
  21.       document.getElementsByTagName("head")[0].appendChild(script);
  22.   } 

你可以將這個函數儲存至一個load_script.js 檔案,然後用該函數來載入其他的指令碼,當要載入多個指令碼時,為了確保正確的載入順序,可以將load_script() 的執行串聯起來,最後如前面說到的放至頁面的底部,這便是一個完美的解決方案了。

 
  1. <script  type="text/javascript"src="load_script.js"></script>    
  2. <script type="text/javascript">  
  3. load_script("file1.js", function()  
  4.  {     
  5.    load_script("file2.js", function()  
  6.      {        
  7.       load_script("file3.js", functio()  {                   
  8. //全部載入後的操作...           
  9.          } );  
  10.       } );  
  11.   } );  
  12. </script>  

3.XMLHttpRequest 指令碼注入

即通過AJAX 方式載入,不過這種方式無法實現跨域載入,不適用於大型網站。

推薦的無阻塞模式
       我們上面做的這些工作當然也已經被那些牛人們完成了,並寫成了一些優秀的JS 類庫以便我們使用,它們均能很好地解決JS 指令碼的阻塞問題,實現並行下載,例如: YUI3、LazyLoad、LABjs 等。
 

【編輯精選】

  1. JavaScript跨域總結與解決辦法
  2. 使用Javascript開發行動裝置 App程式
  3. 10個令人驚奇的HTML5和JavaScript效果
  4. JavaScript初學者應注意的七個細節
【責任編輯:福濤 TEL:(010)68476606】


相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。