最近一直在研究 Javascript 相關的技術。在《Javascript 進階程式設計》有篇章節著重闡述了最佳化 Javascript 代碼的重要性。相信有很多的 Javascript 開發人員在開發的同時或多或少的會接觸到此類的問題。
在大部分情況下,代碼的最佳化並不是實際開發中所需要著重的部分。但是一旦程式碼完成了以後,開發人員總是期待自己的代碼能夠越短越高效越好。結合從書中獲得的知識以及本人實際開發過程中的經驗,下面說明本人所採取的一些花招(也算是照本宣科一下)。
前言
相比指令碼語言,編譯型的語言並不需要太關心最佳化問題。在極大的程度上,編譯時間編譯器都會之行最佳化操作。比如所有的變數、函數、對象等等都會替換成只有處理器才能理解的符號和指標(就是通常所指的可執行檔)。其他的指令碼語言也並不需要過分在意檔案的大小問題,但是 Javascript 則不同。
因為它首先要通過從伺服器端下載原始碼,然後再由用戶端的瀏覽器執行。因此,Javascript代碼的速度被分割成兩部分:下載時間(取決於檔案的大小)和執行速度(取決於代碼演算法)。這篇主要討論的是 Javascript的下載時間最佳化,也就是如何儘可能的縮小 Javascript 檔案本身的容量。
在這裡要記住的一個數字是 1160,這是能放入單個 TCP/IP 包中的位元組數。所以,最好的期望值是能將每個 Javascript 檔案保持在 1160 位元組一下,以擷取最優的下載時間。
刪除注釋
這似乎是是廢話,不過很多開發人員都會忘記。在實際生產環境中,指令碼中的注釋都應該刪除。在開發期間注釋相當的重要,它可以協助團隊理解代碼。但在實際生產環境中,注釋會明顯使指令檔體積變大。刪除它們並不會給指令碼實際運行帶來任何的影響。
刪除定位字元和空格
具有良好縮排和空格的代碼通常都具有良好的可讀性。但是瀏覽器並不需要這些額外的定位字元和空格,所以最好刪除它們。當然也不要忘記函數參數,指派陳述式以及比較操作之間的空格。比如
function showMeTheMoney(money)
{
if (!money) {
return false;
} else {
...
}
}可以最佳化成
function showMeTheMoney(money){if(!money){reutrn false;}else{...}}
這樣可以減少部分容量。
刪除所有的換行
有許多關於在 Javascript 中換行應該存在的思考,但底線都是換行要增加代碼的可讀性。但過分的換行也會造成代碼體積的增加。
可能處於某種原因而不能刪除分行符號,這樣則要保證檔案是 Unix 格式的。因為 Windows、Mac 格式的分行符號用兩個字元表示換行;Unix 僅用一個。所以將檔案轉換成 Unix 格式也可以節約一些位元組數。
替換變數名
這可能是最無聊的一種做法,這通常不是手工完成的。畢竟變數的名稱對解譯器來說毫無意義(只是對開發人員來說會更友好一些),在生產環境中將描述性的變數名替換成更簡單、更短的名稱也可以縮減一部分體積。比如上述的代碼可以縮減成:
function sm(m){if(!m){reutrn false;}else{...}}
這樣雖然看起來會比較的頭痛,不過實際之行效果是一樣的。
使用工具
實際使用上述的方法可能會有一些困難,幸好有現成的外部工具能完成這些步驟。下面簡單的介紹幾個:
ECMAScript Cruncher:http://saltstorm.net/depo/esc/
JSMin(The JavaScript Minifier): http://www.crockford.com/javascript/jsmin.html
Online JavaScript Compressor.:http://dean.edwards.name/packer/
我猜你會有興趣看下這篇文章。
其他方法
替換布爾值
對於比較來說,true 就等於 1,false 就等於 0 。因此,指令碼包含的字面量 true 都可以用 1 來替換,而 false 可以用 0 來替換。對於 true 節省了 3 個位元組,而 false 則節省了 4 個位元組。
縮短否定檢測
代碼中常常會出現檢測某個值是否有效語句。而大部分條件非的判斷就是判斷某個變數是否為 undefined、null 或者 false,比如:
if (myValue != undefined) {
// ...
}
if (myValue != null) {
// ...
}
if (myValue != false) {
// ...
}
這些雖然都正確,但用邏輯非操作符也可以有同樣的效果:
if (!myValue) {
// ...
}
這樣的替換也可以節省一部分位元組。
使用數組和對象字面量
這個比較好理解,比如一下兩行是相同的:
var myArray = new Array;
var myArray = [];
然而第二行比第一行短很多,而且也能非常容易的理解。類似的還有對象聲明:
var myObject = new Object;
var myObject = {};
舉個例子,比如下面的語句:
var mySite = new Object;
mySite.author = "feelinglucky";
mySite.location = "http://www.gracecode.com";
這樣寫也可以非常容易的理解,並且短很多:
var mySite = {author:"feeinglucky", location:"http://www.gracecode.com"};
好的,這期就到這裡。就向上面說的,Javascript 代碼的速度被分割成兩部分:下載時間(取決於檔案的大小)和執行速度(取決於代碼演算法)。這次討論的是下載時間方面的最佳化,下期討論之行速度方面的最佳化(這樣看起來非常有技術含量,不是麼)。
下面布置家庭作業。或許大家會有興趣瞭解下 jQuery 是怎麼把自己 70KB 的代碼壓縮至 20KB 左右的。