前端效能最佳化:Javascript的載入順序

來源:互聯網
上載者:User

文章簡介:35條Javascript最佳實務.

相信很多與頁面打過交道的同學都對 Yahoo 的 Best Practices for Speeding Up Your Web Site 不陌生。而這 35 條最佳實務中,對 Javascript 的載入順序的要求是:Put Scripts at the Bottom。因為根據HTTP/1.1 specification 看來,在同一時間載入兩個檔案是最理想的,而 Javascript 指令碼會阻礙平行下載。Steve 說那是 2008 – 2009 那個時代用的。現在,載入 Javascript 已經有了革命性的化變。

在開講之前,有一個必須解決的問題是:為什麼我們要把 JS 檔案放在 </body> 之前的最底部。根本原因是,它不能平行下載。而其實並不是所有瀏覽器都不支援。現在大部分瀏覽器都支援 Script 的平行下載,除了老掉牙的 IE6&7、Firefox 2&3.0、 Safari 3、Chrome 1。但我們最熟悉的老掉牙同學 IE6 (或以IE為核的那些殼)還是中國(甚至世界上)市場上佔用率最高的瀏覽器,因此我們需要一個折衷的方案。

一、分析

我們有6種方法可以實現平行(NON-Blocking)下載:

  • XHR Eval – 用 XHR 下載,並 eval() 執行 responseText.。
  • XHR Injection – 用 XHR 下載,在頁面中動態建立一個 script 元素,並將 responseText 作為其 text 。
  • Script in Iframe – 把指令碼放在 HTML 中,使用 ifame  來下載它。
  • Script DOM Element – 動態建立一個 script 元素,把 src 指向指令碼URL.
  • Script Defer – 給 script 標添加 defer 屬性
  • document.write Script Tag – 利用 document.write 把 <script src=""> 添加到 HTML 中。但這個只對 IE 有效。

相容性可看下圖:

二、方案

對於究竟應該使用哪種方案。這完全取決於你需要自身的需要。這張圖描述了什麼時候使用什麼方法:

從總體上看來,Script DOM Element 是比較好的方案。NCZ 的部落格上提過,目前最好的技術是:

建立兩個 JavaScript  檔案。第一個檔案只提供動態下載 Javascript 的代碼,第二個檔案則包含所有其他頁面所需指令碼的檔案。

像 <script> 在頁部(</body> 之前)引入第一個檔案。

建立第二個 <script> 來執行下載第二個 Javascript 檔案的函數和其他的初始化代碼。

三、實現代碼

根據上面的提到的技術。NCZ 推薦第一個檔案只包含相應的實現第二個檔案動態載入的代碼:

function loadScript(url, callback){

    var script = document.createElement("script")
    script.type = "text/javascript";

    if (script.readyState){  //IE
        script.onreadystatechange = function(){
            if (script.readyState == "loaded"
                    script.readyState == "complete"){
                script.onreadystatechange = null;
                callback();
            }
        };
    } else {  //Others
        script.onload = function(){
            callback();
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

然後,我們可以在頁面中這樣做:

<script type="text/javascript" src="http://your.cdn.com/first.js"></script>
<script type="text/javascript">
loadScript("http://your.cdn.com/second.js", function(){
    //初始化你的代碼
});
</script>

在 HTML5 上,我們可以使用 async 屬性。這個 HTML 屬性的作用正是我們需要的 NON-Blocking 下載技術。雖然目前支援的瀏覽器並不多(似乎只有 Firefox 3.6+ ?),但給需要平行下載的 Javascript(按照方案看來,一般是第一個 JS 檔案) 加上這個屬性,也不會影響其他不支援的瀏覽器,所以,是推薦使用的。

<script type="text/javascript" async src="foo.js"></script>

四、實踐

YUI3 的 Loader 使用了 NCZ 的這樣的方法。而在支付寶。我們也使用了類似的方法。這裡簡單說一下。

<script type="text/javascript" charset="utf-8">
// 配置 combo 服務的 PATH
araleConfig = {
 combo_host: "http://domain.com",
 combo_path: "/path/to/the/compressed/file"
}
</script>

<script type="text/javascript" src="core.js"></script>

在使用的時候,再利用 Loader.use() 來實現代碼的動態載入。當然,這裡不僅僅是動態載入,還有一定的緩衝機制在裡面。建議你查看相關的 combo 服務的技術。目前支付寶前端架構組的工友們,已經在這一塊取得了一些不錯的進展(根據測試報告,速度是非常不錯的,可能會在適當的時候開源出來)。

五、總結

前端效能最佳化方面。還有很多東西可以做。並且,隨著 HTML5 技術的出現和 Javascript 技術的不斷創新,相信還有更多東西是值得期待。前端們,加油吧,未來有很多東西應該是由你來主導的。



相關文章

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 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。