Javascript 載入效能最佳化__Java

來源:互聯網
上載者:User
阻塞特性

瀏覽器對javascript的處理主要有2部分:下載和執行 下載在有些瀏覽器中是並行的,有些瀏覽器中是串列的,如IE8、Firefox3、Chrome2都是串列下載的 執行在所有瀏覽器中預設都是阻塞的,當js在執行時不會進行html解析等其它操作

阻塞特性:

javascript有個阻塞特性,當瀏覽器執行javascript代碼時,不能同時做其它任何事情。無論當前javascript代碼是內嵌還是在外鏈檔案中,頁面的下載和渲染都必須停下來等待指令碼執行完成。瀏覽器在下載和執行指令碼是進出現阻塞的原因在於,指令碼可能會改變頁面或javascript的命名空間,它們對後面頁面內容造成影響。 一、指令碼位置

瀏覽器在碰到一個引入外部javascript檔案的<script>標籤時會停下所有工作來下載並解析執行它,在這個過程中,頁面渲染和使用者互動完全被阻塞了。例:

<html> <head> <title>無標題文檔</title> <link rel="stylesheet" type="text/css" href="styles.css" /> <script type="text/javascript" src="file1.js"></script> <script type="text/javascript" src="file2.js"></script> <script type="text/javascript" src="file3.js"></script> </body> </head> <body> <p>頁面的內容。。。</p></body></html>

由於指令碼的阻塞特性,頁面會在3個javascript檔案全部下載執行完成後,頁面才會繼續渲染,把指令碼放在頁面頂部會導致明顯延遲,通常表現為顯示空白頁,使用者無法瀏覽內容,也無法與頁面互動。

ie8+、firefox 3.5+、safari4+、chrome2+都允許並行下載javascript檔案,但是在下載的過程中仍然會阻塞圖片等其它資源的下載。

由於指令碼會阻塞頁面其它資源的下載,因此推薦將javasrcipt盡量放到body標籤的底部,以減少對整個頁面下載的影響。 二、組織指令碼

由於<script>標籤在下載時會阻塞頁面的渲染,所以減少<script>標籤數量有助於改善這一情況。建議將多個javascript檔案合并為一個,這樣可以減少效能的消耗。同時也可以減少請求的數量。

參考:在服務端合并和壓縮javascript和CSS檔案 三、無阻塞指令碼 1、延遲指令碼

HTML4 為<script>標籤定義了一個defer 屬性,它能使這段代碼順延強制,然而該屬性只有IE4+支援,因此它不是一個理想的跨瀏覽器解決方案。聲明了defer 屬性的script會在DOM載入完成,window.onload 事件觸發前被解析執行:

<html> <head> <title>script defer example</title> </body> </head> <body><script defer> alert('defer');</script><script> alert('script');</script><script> window.onload = function(){ alert('load'); }</script></body></html>

這段代碼在支援defer屬性的瀏覽器彈出順序是:script、defer、load;不支援defer屬性的瀏覽器彈出的順序是defer、script、load。 2、動態指令碼元素

<script type="text/javascript">function loadScript(url, callback) { var script = document.createElement('script') script.type = 'text/javascript'; if (script.readyState) { //for ie script.onreadystatechange = function() { if (script.readyState == 'loaded' || script.readyState == 'complete') { script.onreadystatechange = null; callback(); } }; } else { //other browser script.onload = function() { callback(); }; } script.src = url; document.getElementsByTagName('head')[0].appendChild(script);}</script>

loadscript函數用法

<script type="text/javascript"> //單個檔案 loadScript('file1.js', function(){ alert('loaded!'); }); //多個檔案 loadScript('file1.js', function(){ loadScript('file2.js',function(){ loadScript('file3.js', function(){ alert('all files loaded!'); }); }); });</script>

這種技術的重點在於:無論何時啟動下載,檔案的下載和執行過程不會阻塞頁面其它進程,你甚至可以將代碼放在頁面的head地區而不影響頁面的其它部分(下載該檔案的http連結除外)。 3、XMLHttpRequest 指令碼注入

此技術會先建立一個XHR對象,然後用它下載javascript檔案,最後建立動態script元素將代碼注入到頁面中。

<script type="text/javascript">var xhr = new XMLHttpRequest();xhr.open('get', 'file1.js', true);xhr.onreadystatechange = function() { if (xhr.status >= 200 && xhr.status <300 || xhr.status == 304) { var script = document.createElement('script'); script.type = 'text/javascript'; script.text = xhr.responseText; document.body.appendChild(script); }};xhr.send(null);</script>

這種方法優點是可以直接下載javascript代碼但不立即執行。由於代碼是在<script>標籤之外返回的,因此下載後不會自動執行,這使得是可以把指令碼延遲到你準備好的時候。這種方法的局限性在於javascript檔案必須與所請求的頁面處於相同的域,這意味著javascript檔案不能從cdn下載,因此不適合大型網站或項目。 四、推薦的無阻塞載入方式 1、YUI3的方式 2、LazyLoad(1.5k)

Yahoo!Search工程師Ryan Grove建立的一個通用的消極式載入工具,是loadScript()函數的增強版。

用法樣本:

<script type="text/javascript" src="lazyload-min.js"></script><script type="text/javascript"> LazyLoad.js('the-reset.js', function(){ Application.init(); });</script>

LazyLoad同樣支援多個javascript檔案,並能保證在所有瀏覽器中都可以按正確的順序執行。要載入多個javscript檔案,只需要給LazyLoad.js()y方法傳入一個url數組:

<script type="text/javascript" src="lazyload-min.js"></script><script type="text/javascript"> LazyLoad.js(['first.js', 'the-reset.js'], function(){ Application.init(); });</script>

項目地址:https://github.com/rgrove/lazyload 3、LABjs(4.7k)

LABjs是Kyle Simpson受Steve Sounders的啟發實現的無阻塞載入工具。用法樣本:

<script type="text/javascript" src="lab.js"></script><script type="text/javascript"> $LAB.script('the-reset.js') .wait(function(){ Application.init(); });</script>

$LAB.script()方法用來定義需要下載的javascript檔案,$LAB.wait()用來指定檔案下載並執行完畢後所調用的函數。

要下載多個javscript檔案,只需鏈式調用另一個$LAB.script()方法:

<script type="text/javascript" src="lab.js"></script><script type="text/javascript"> $LAB.script('first.js') .script('the-reset.js') .wait(function(){ Application.init(); });</script>

LABjs與眾不同的是它管理依賴關係的能力。通常來說,連續的<script>標籤意味著檔案逐個下載並按順序執行。

LABjs允許使用wait()方法來指定哪些檔案需要等待其它檔案。上面的例子中first.js不能保證會在the-reset.js的代碼前執行,為了確保這一點,必須在第一個script()方法後調用wait():

<script type="text/javascript" src="lab.js"></script><script type="text/javascript"> $LAB.script('first.js').wait() .script('the-reset.js') .wait(function(){ Application.init(); });</script>

項目地址:http://labjs.com/ 4、SeaJS(7.5k)

SeaJS 是淘寶玉伯開發的一個遵循 CommonJS 規範的模組載入架構,可用來輕鬆愉悅地載入任意 javascript 模組。詳細請參考:http://seajs.com/docs/ 5、do 架構(3.5k)

Do是豆瓣網kejun開發的一個很輕量的Javascript開發架構。目前do.min.js。它的核心功能是對模組進行組織和載入。載入採取並行非同步隊列的策略,並且可以控制執行時機。Do可以任意置換核心類庫,預設是jQuery。

項目地址:https://github.com/kejun/Do 6、RequireJS(13.1k)

項目地址:http://requirejs.org/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.