<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    憨厚生

    ----Java's Slave----
    ***Java's Host***

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      165 隨筆 :: 17 文章 :: 90 評論 :: 0 Trackbacks
    轉 http://www.cnblogs.com/yslow/archive/2009/04/29/1446236.html

    耦合異步腳本

    英文原文地址

     

    最近我的工作都是圍繞異步加載外部腳本(loading external scripts asynchronously) 展開。當外部腳本以普通方式加載時(<script src="...">) 會阻塞頁面內所有其它資源的下載和腳本下方元素的渲染.你可以查看將腳本放在底部(Put Scripts at the Bottom)的樣例的效果. 異步加載腳本會避免阻塞行為進而更快的加載頁面.

    異步加載腳本產生的問題是內嵌腳本使用外部腳本中定義的符號的問題. 如果內嵌腳本使用了異步加載的外部腳本符號,競爭條件下可能會導致未定義的符號錯誤。因此有必要保證異步腳本和內嵌腳本以下面方式進行耦合:在異步腳本下載完畢之前內嵌腳本不能被執行。

    下面有幾種方式耦合異步腳本.

    • window’s onload - 內嵌腳本可以嘗試使用窗口的onload事件. 實現起來非常簡單,但是內嵌腳本不會盡可能早的執行.
    • script’s onreadystatechange - 內嵌腳本可以嘗試使用腳本的onreadystatechangeonload 事件(在所有流行的瀏覽器里面均需要你自己來實現) 代碼比較長而復雜,但是可以確保在腳本下載完畢之后馬上執行內嵌腳本.
    • hardcoded callback - 外部腳本可以修改為通過一個回調函數(callback function)來明確的調用內嵌腳本,如果外部腳本和內嵌腳本是一個團隊開發的話,這樣是沒有問題的,但如果使用第3方的腳本,這就提供不了必要的靈活性。

    在這個博客帖子里我討論兩個問題: 如何使用異步腳本加快頁面,如何通過Degrading Script Tags模式耦合外部腳本和內嵌腳本. 我通過我最近剛剛完成的一個項目UA Profiler results sortable圖表來演示. 我還使用了Stuart Langridge的 sorttable排序腳本. 把他的腳本增加到我的頁面并排序結果耗費了我大約5分鐘.通過增加一點使用異步腳本和耦合腳本的工作量我可以使這個頁面提高30%的加載速度

    普通Script標記

    最初我使用普通的方法(<script src="...">)將Stuart Langridge的sorttable排序腳本加入到UA Profiler, 例子見Normal Script Tag. HTTP瀑布圖見圖1.

    普通Script標記
    圖1: 普通Script標記的瀑布圖

    表格排序工作正常,但由于它使頁面慢了許多,我并不滿意. 圖1中我們可以看到腳本(sorttable-async.js)阻塞了頁面內唯一的后繼HTTP請求(arrow-right- 20X9.gif), 造成頁面加載變慢. 瀑布圖是使用Firebug 1.3 beta來產生的(你也可以使用httpwatch基調網絡webwatch工具來查看效果)。 新版本的Firebug在onload事件發生的地方標記了一條紅豎線. (藍豎線是DOMContentLoaded事件.) 對于普通Script標記 來說, onload 事件在第487毫秒產生.

    異步加載腳本

    對初始頁面渲染來說,腳本sorttable-async.js是沒有必要的 - 表格被渲染之后才會排序. 這種情況(外部腳本不會被初始頁面使用)是可以使用異步腳本加載的主要特征 . 例子異步加載腳本 使用DOM方式異步加載:

    var script = document.createElement('script');
    script.src = "sorttable-async.js";
    script.text = "sorttable.init()"; // 這會在下面解釋
    document.getElementsByTagName('head')[0].appendChild(script);

    異步加載腳本的HTTP瀑布圖見圖2。注意我是如何使用異步加載技術來避免阻塞行為的 - sorttable-async.js和arrow-right-20×9.gif 被同時下載. onload時間為429毫秒.

    異步加載腳本
    圖2: 異步加載腳本的HTTP瀑布圖

    John Resig介紹的 Degrading Script Tags 模式

    例子異步加載腳本使頁面加載更快了,但仍舊有進一步提高的空間. 默認sorttable排序是通過在onload事件中增加sorttable.init()來觸發。當外部腳本被加載完畢后內嵌腳本立即調用sorttable.init()能進一步提升性能. 在這種情況下,我使用的API僅僅是一個函數,但是我將嘗試一個足夠靈活的模式來支持更復雜的情況。

    前面我列出了各種內嵌腳本和外部異步腳本耦合的方法: window’s onload, script’s onreadystatechange, 和 hardcoded callback. 這里,我使用了來自John Resig的被稱為Degrading Script Tags模式的技術。 John描述了如何耦合一個內嵌腳本和外部腳本,例如:

    <script src="jquery.js">
    jQuery("p").addClass("pretty");
    </script>

    他提到的這個方法是使內聯腳本在外部腳本下載完畢之后才開始執行。使用這種方式耦合內嵌腳本和外部腳本有幾個好處:

    • 更簡單 - 將2個script標記替換為1個script標記
    • 更清晰 - 內嵌代碼依賴于外部腳本的關系更為明顯
    • 更安全 - 如果外部腳本下載失敗,內嵌腳本就不會執行,避免拋出未定義的符號錯誤

    當使用異步加載外部腳本時這也是一個很棒的模式。為了使用這個技術,我必須修改我的內嵌代碼和外部腳本. 對于內嵌代碼, 我增加了第3行來設置 script.text的屬性. 為了耦合代碼, 我在sorttable-async.js末尾增加了如下代碼:

    var scripts = document.getElementsByTagName("script");
    var cntr = scripts.length;
    while ( cntr ) {
    var curScript = scripts[cntr-1];
    if ( -1 != curScript.src.indexOf('sorttable-async.js') ) {
    eval( curScript.innerHTML );
    break;
    }
    cntr--;
    }

    此代碼遍歷網頁的所有腳本,直到它找到腳本塊本身 (此時腳本的src屬性包含sorttable-async.js),然后利用eval將代碼(sorttable.init ())增加到腳本觸發運行. (備注:雖然內嵌代碼使用text屬性增加代碼內容,但是需要使用innerHTML獲取代碼. 這是代碼跨瀏覽器工作的必要保證) 經過這樣的優化,外部腳本不會阻塞其它資源的下載,同時,內嵌代碼也會盡可能早的執行.

    延遲加載

    通過延遲加載能更快的加載頁面 (通過onload事件動態加載). 例如 Lazyload 是在onload 事件中包含如下代碼:

    window.onload = function() {
    var script = document.createElement('script');
    script.src = "sorttable-async.js";
    script.text = "sorttable.init()";
    document.getElementsByTagName('head')[0].appendChild(script);
    }

    這種情況絕對需要腳本耦合技術,在onload事件里面的代碼sorttable.init()不會被執行,因為此時onload事件已經發生,而sorttable-async.js還沒被下載。延遲加載的好處是使onload事件更快的發生,見圖3。紅豎線表明onload事件發生在第320毫秒.

    延遲加載
    圖3: 延遲加載的HTTP瀑布圖

    結論

    通過避免通常的阻塞行為,異步加載腳本和延遲加載腳本可以提高網頁的加載時間. 下面是增加不同版本的sorttable排序例子代碼:

    以上時間指的是onload事件發生的時間。



    posted on 2009-11-04 15:25 二胡 閱讀(232) 評論(0)  編輯  收藏 所屬分類: JS
    主站蜘蛛池模板: 在线观看无码的免费网站| 亚洲av永久综合在线观看尤物| 成人性生交大片免费看无遮挡| 国产一区二区三区免费观看在线| 久久久久亚洲精品无码网址色欲 | 久久精品国产亚洲网站| 拔擦拔擦8x华人免费久久| 114一级毛片免费| 久久午夜免费鲁丝片| 久久高潮一级毛片免费| 亚洲国产精品网站在线播放| 亚洲人和日本人jizz| 亚洲网红精品大秀在线观看| 亚洲精品自在在线观看| 久久精品国产精品亚洲人人 | 亚洲av无码一区二区三区四区| 亚洲熟妇色自偷自拍另类| 亚洲va久久久噜噜噜久久| 中文字幕人成人乱码亚洲电影| 波多野结衣一区二区免费视频| 成人黄动漫画免费网站视频| 曰曰鲁夜夜免费播放视频| 99re免费99re在线视频手机版| 拍拍拍无挡免费视频网站| 中文字幕无线码中文字幕免费| 四虎精品成人免费视频| 一区二区三区免费在线视频 | 热re99久久6国产精品免费| 久久精品国产免费一区| 成人国产精品免费视频| 成在线人免费无码高潮喷水| 久久久受www免费人成| 99在线免费视频| 久久久精品免费国产四虎| 七色永久性tv网站免费看| 一个人免费日韩不卡视频| 在线观看免费中文视频| 97免费人妻无码视频| 蜜桃视频在线观看免费网址入口| 久久精品a一国产成人免费网站| 久久久久久国产精品免费免费 |