JavaScript - 程式碼壓縮與最佳化

壓縮程式碼

在正式上線前,可以將JavaScript程式碼進行壓縮,減少檔案大小,讓使用者下載更快,也節省頻寬。方法有手動與自動兩種。

手動(效果不好):

  • 刪除「長變數名」、「註解」、「空格」、「換行」…
  • true改用1, false改用0

缺點,易產生錯誤。

自動(建議使用):

使用工具,自動化產生壓縮式的JavaScript檔案:


JavaScript自動化壓縮工具還有很多,各位可以自行上網找一套自己喜歡的來用。未來新的 Visual Studio 11 / .NET Framework 4.5 會將自動化壓縮最佳化 JavaScript 與 CSS 等特性加入。

JavaScript 程式碼最佳化

這個部份提出的都是自動化壓縮工具比較幫不上忙,有些是邏輯技巧,有些是程式技巧,順序上,應該先進行內部程式碼最佳化,然後再使用壓縮工具來加速提升。

宣告變數

JavaScript中未宣告的變數(函式中也一樣)預設為全域變數,全域變數只有在瀏覽器關閉後才釋放。

name = Bruce;

使用內建函數

內建函數都已編譯過,執行速度會比即時編譯的JavaScript快很多。

巢狀if

將出現率最多的情況放在前面,另外,使用switch語句替代巢狀if/else if。

整合同性質工作

指令碼中程式行數越少,執行時間越快,將同性質的指令碼集中一次處理,例如,例如宣告變數:

// 宣告方法一
var name="Bruce";
var age = 18;
var birthday = new Date(2010/10/10);

// 宣告方法二
var name="Bruce", age=18,birthday=new Date(2010/10/10);

節約使用DOM

JavaScript對DOM的處理可能是最耗時費力,盡量減少DOM的操作,例如,為ul新增10個li,我們的處理方式可以有:

var oUL = document.getElementById("ulItem");
for (var i=0; i<10; i++){
  var oLI = document.createElement("li");
  oUL.appendChild(oLI); //10次
  oLI.appendChild(document.createTextNode("Item" + i)); //10次
}

共執行20次DOM操作。其實我們可以有更好的選擇:

var oUL = document.getElementById("ulItem");
var oTemp = document.createDocumentFragment();
for (var i=0; i<10; i++){
  var oLI = document.createElement("li");
  oLI.appendChild(document.createTextNode("Item" + i));
  oTemp.appendChild(oLI);
}
oUL.appendChild(oTemp); //1次

共執行1次DOM操作。20 : 1,相信那段程式碼效率一眼就可以看出來。

[KKBruce補充]可多利用 document.createDocumentFragment 來最佳化相關程式碼。

最佳化的影響

壓縮程式碼與程式碼最佳化通常會大大影響「可讀性」,不佳的可讀性讓後續「維護」困難度升高,所以正常做法是分為上線和開發兩個版本。

  • 上線:使用壓縮及最佳化,加速下載速度,提高執行效能。
  • 開發:保持良好程式架構和註解等,提高可讀性及減低維護難度。

8 則留言:

  1. 20:1...不是這樣比的吧...XD
    你怎麼看出來第二段程式碼比第一段的效能好?
    DocumentFragments are DOM Nodes.

    回覆刪除
  2. 文件的第二句就回答你了呀:「They are never part of the main DOM tree.」。

    回覆刪除
  3. 我是說你的範例應該是寫錯了...
    不只是語法錯誤,
    你這樣寫,第二段的效能沒有比第一段好,
    我想你應該沒實際測過.

    回覆刪除
  4. 你可以直接run下面的範例...
    http://jsfiddle.net/z3caE/
    這是把你的範例直接貼上去的...

    回覆刪除
    回覆
    1. http://jsperf.com/createdocumentfragment-test
      http://jsfiddle.net/z3caE/3/ <-- 我將筆數加至 20000,比較看得出差異。

      在不同瀏覽器(不同JavaScript引擎)分數差異極大:

      Chrome 27 , 怪異。我重覆按 Run 執行,有時ce > cdf,有時 ce = cdf,有時 ce < cdf。
      IE 10 , cd > cdf。
      FF 21 , cd < cdf。

      三個瀏覽器三個結果。@_@

      公說公有理,婆說婆有理。(嘆氣中)

      刪除
  5. 在IE上的差異比較明顯.(我是用IE9)
    另外你可以將第二個範例中的兩行對調.

    oLI.appendChild(document.createTextNode("Item" + i));
    oTemp.appendChild(oLI);
    換成
    oTemp.appendChild(oLI);
    oLI.appendChild(document.createTextNode("Item" + i));
    在IE下就會發現差很大.這時createDocumentFragment的那段才會比原本的快.
    http://jsfiddle.net/z3caE/4/
    而這也是為什麼我會說你給的範例有誤...因為兩段的動作順序不一樣,所以在比較上就會有差.

    回覆刪除
  6. 從來沒發現我兩個範例的順序不一楚 Orz Orz Orz …

    這樣一來,三個瀏覽器的的結果是一致的。

    非常感謝指教。

    回覆刪除

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。