Javascript/jquery非同步載入使用方法詳解(1/2)

來源:互聯網
上載者:User

一、同步載入與非同步載入的形式
1. 同步載入
我們平時最常使用的就是這種同步載入形式:
<script src="http://yourdomain.com/script.js"></script>同步模式,又稱阻塞模式,會阻止瀏覽器的後續處理,停止了後續的解析,因此停止了後續的檔案載入(如映像)、渲染、代碼執行。
 js 之所以要同步執行,是因為 js 中可能有輸出 document 內容、修改dom、重新導向等行為,所以預設同步執行才是安全的。
以前的一般建議是把<script>放在頁面末尾</body>之前,這樣儘可能減少這種阻塞行為,而先讓頁面展示出來。
簡單說:載入的網路 timeline 是瀑布模型,而非同步載入的 timeline 是並行存取模型。
2. 常見非同步載入(Script DOM Element)

 代碼如下 複製代碼
(function() {
     var s = document.createElement('script');
     s.type = 'text/javascript';
     s.async = true;
     s.src = 'http://yourdomain.com/script.js';
     var x = document.getElementsByTagName('script')[0];
     x.parentNode.insertBefore(s, x);
 })();

非同步載入又叫非阻塞,瀏覽器在下載執行 js 同時,還會繼續進行後續頁面的處理。


這種方法是在頁面中<script>標籤內,用 js 建立一個 script 元素並插入到 document 中。這樣就做到了非阻塞的下載 js 代碼。
async屬性是HTML5中新增的非同步支援,見後文解釋,加上好(不加也不影響)。
此方法被稱為 Script DOM Element 法,不要求 js 同源。
將js程式碼封裝裹在匿名函數中並立即執行的方式是為了保護變數名泄露到外部可見,這是很常見的方式,尤其是在 js 庫中被普遍使用。
例如 Google Analytics 和 Google+ Badge 都使用了這種非同步載入代碼:

 代碼如下 複製代碼
(function() {
     var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 })();(function()
    {var po = document.createElement("script");
    po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(po, s);
 })();

但是,這種載入方式在載入執行完之前會阻止 onload 事件的觸發,而現在很多頁面的代碼都在 onload 時還要執行額外的渲染工作等,所以還是會阻塞部分頁面的初始化處理。


3. onload 時的非同步載入

 代碼如下 複製代碼
(function() {
     function async_load(){
         var s = document.createElement('script');
         s.type = 'text/javascript';
         s.async = true;
         s.src = 'http://yourdomain.com/script.js';
         var x = document.getElementsByTagName('script')[0];
         x.parentNode.insertBefore(s, x);
     }
     if (window.attachEvent)
         window.attachEvent('onload', async_load);
     else
         window.addEventListener('load', async_load, false);
 })();

這和前面的方式差不多,但關鍵是它不是立即開始非同步載入 js ,而是在 onload 時才開始非同步載入。這樣就解決了阻塞 onload 事件觸發的問題。
補充:DOMContentLoaded 與 OnLoad 事件
DOMContentLoaded : 頁面(document)已經解析完成,頁面中的dom元素已經可用。但是頁面中引用的圖片、subframe可能還沒有載入完。
OnLoad:頁面的所有資源都載入完畢(包括圖片)。瀏覽器的載入進度在這時才停止。
這兩個時間點將頁面載入的timeline分成了三個階段。
4.非同步載入的其它方法

由於Javascript的動態特性,還有很多非同步載入方法:
1.XHR Eval
2.XHR Injection
3.Script in Iframe
4.Script Defer
5.document.write Script Tag
6.還有一種方法是用 setTimeout 延遲0秒 與 其它方法組合。
XHR Eval :通過 ajax 擷取js的內容,然後 eval 執行。

 代碼如下 複製代碼
var xhrObj = getXHRObject();
 xhrObj.onreadystatechange =
   function() {
     if ( xhrObj.readyState != 4 ) return;
     eval(xhrObj.responseText);
   };
 xhrObj.open('GET', 'A.js', true);
 xhrObj.send('');Script in Iframe:建立並插入一個iframe元素,讓其非同步執行 js 。
var iframe = document.createElement('iframe');
 document.body.appendChild(iframe);
 var doc = iframe.contentWindow.document;
 doc.open().write('<body onload="insertJS()">');

 doc.close();GMail Mobile:頁內 js 的內容被注釋,所以不會執行,然後在需要的時候,擷取script元素中 text 內容,去掉注釋後 eval 執行。

 代碼如下 複製代碼
<script type="text/javascript">
 /*
 var ...
 */
 </script>

首頁 1 2 末頁
相關文章

聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.