Web性能優化最佳實踐中最重要的一條是減少HTTP請求,它也是YSlow中比重最大的一條規則。減少HTTP請求的方案主要有合並JavaScript和CSS文件、CSS Sprites、圖像映射(Image Map)和使用Data URI來編碼圖片。CSS Sprites和圖像映射現在已經隨處可見了,但由於IE6和IE7不支持Data URI以及性能問題,這項技術尚未大量使用。目前大部分網頁中的JavaScript和CSS文件數量和開發時一致,少量的網頁會根據實際情況采取本地合並,這些合並中相當多的是有選擇地手動完成,每次新的合並都需要重新在本地完成並上傳到服務器,比較的隨意和繁瑣,同樣文件的壓縮也有類似的情況。而利用服務端的合並和壓縮,我們就可以按照開發的邏輯盡可能讓文件的顆粒度變小,利用網頁中URL的規則來自動實現文件的合並和壓縮,這會相當的靈活和高效。
YUI Combo Handler
2008年7月YUI Team宣布在YAHOO! CDN上對YUI JavaScript組件提供Combo Handler服務。Combo Handler是Yahoo!開發的一個Apache模塊,它實現了開發人員簡單方便地通過URL來合並JavaScript和CSS文件,從而大大減少文件請求數。比如在頁面上使用YUI2的Rich Text Editor組件需要引入多個JavaScript文件,常用方式如下:
<script src="http://yui.yahooapis.com/2.8.0r4/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/container/container_core-min.js"></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/menu/menu-min.js"></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/element/element-min.js"></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/button/button-min.js"></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/editor/editor-min.js"></script>
而使用Combo Handler服務之後,則上述的代碼可以寫為:
<script src="http://yui.yahooapis.com/combo?
2.8.0r4/build/yahoo-dom-event/yahoo-dom-event.js&
2.8.0r4/build/container/container_core-min.js&
2.8.0r4/build/menu/menu-min.js&
2.8.0r4/build/element/element-min.js&
2.8.0r4/build/button/button-min.js&
2.8.0r4/build/editor/editor-min.js"></script>
除了代碼的可讀性稍稍有一點點降低外,使用Combo Handler服務大大的降低了HTTP請求數,同時也減少了URL代碼量,這對於Web性能優化來講至關重要。所以,隨後YUI從2.6.0開始,其核心組件YUI Loader內置了Combo Handling功能,即使用YUI Loader時,通過配置combine屬性就可以把要加載的多個JavaScript或CSS文件按照使用Combo Handler服務的形式合並起來,這時只要靜態文件的服務器支持Combo Handler就行了。在YUI中當combine配置為true時,CDN默認是使用Yahoo! CDN(http://yui.yahooapis.com),所以沒有任何問題。這正是YUI最迷人的地方之一。
遺憾的是http://yui.yahooapis.com在中國的速度並不佳,本來中國雅虎提供http://cn.yui.yahooapis.com/ ,但尚未提供Combo Handler服務,同時因種種原因,其更新在YUI 2.7.0之後就停滯了。更糟糕的是Yahoo!開發的支持Combo Handler的Apache模塊雖然據傳有計劃開源,但至少現在依舊是私有技術,要使用就需要自己實現類似功能,所以國內類似技術的應用並不太多。
Minify
在Google Code上有一個PHP的開源項目叫Minify,它可以合並、精簡、Gzip壓縮和緩存JavaScript和CSS文件。其文件合並功能就非常類似Combo Handler,只不過URL的語法稍微有點不同。如果Yahoo! CDN安裝了Minify,那麼上面Rich Text Editor的代碼用Minify的默認格式來寫就是:
<script src="http://yui.yahooapis.com/min/f=
2.8.0r4/build/yahoo-dom-event/yahoo-dom-event.js,
2.8.0r4/build/container/container_core-min.js,
2.8.0r4/build/menu/menu-min.js,
2.8.0r4/build/element/element-min.js,
2.8.0r4/build/button/button-min.js,
2.8.0r4/build/editor/editor-min.js"></script>
本地使用Minify很簡單,只需要Apache + PHP環境就OK了:
安裝好Apache + PHP (Windows、Mac)。
下載Minify源碼,解壓,然後把min文件夾復制到指定的根目錄下,比如localhost。這時URL的寫法大概是http://localhost/min/f=。..
啟用Apache的Mod Rewrite模塊,然後在min文件夾下新建.htaccess文件,並添加如下Rewrite規則:
<IfModule mod_rewrite.c>
RewriteEngine on
# You may need RewriteBase on some servers
# 如果做了所有的開啟Mod Rewrite的設置依舊無效,請城市嘗試啟用下面這句
#RewriteBase /min
# rewrite URLs like "/min/f=..." to "/min/?f=..."
RewriteRule ^([bfg]=.*) index.php?$1 [L,NE]
</IfModule>
如果不啟用Mod Rewrite功能,則Minify的URL會類似http://localhost/min/index.php?f=…,這對客戶端和中間服務器的緩存不利,而啟用了Mod Rewrite之後的URL類似http://localhost/min/f=…,不僅解決前面問題且更短。
4. 配置Minify,即編輯min/config.php文件
$min_enableBuilder = true;
//本地使用時可以通過http://dwn/min/builder/來進行配置,外部使用時請設置為false
//$min_cachePath = 'c:WINDOWSTemp';
//$min_cachePath = '/tmp';
//$min_cachePath = preg_replace('/^d+;/', '', session_save_path());
//選擇其一,去掉注釋設置臨時緩存目錄,這樣可以減少程序運算提高性能
$min_serveOptions['maxAge'] = 1800;
//設置浏覽器緩存的時間,為了提升性能建議這個時間設置盡可能的長,比如315360000
//如果需要在不改變URL的情況下更新靜態文件,可以采用類似時間戳的方式,
//如http://localhost/min/f=example/example.css&20100601.css
//建議靜態文件采用版本號管理,每次修改都需要升級版本號,這樣就無需時間戳了
//如http://localhost/min/f=example/example_1_0_1.css
$min_serveOptions['minApp']['maxFiles'] = 10;
//參數f獲取參數的個數,即合並的文件個數,這個數量完全可以增大,比如50,
//當然可能會遇到URL最大值問題,後會有解釋
$min_documentRoot = '';
//$min_documentRoot = substr(__FILE__, 0, strlen(__FILE__) - 15);
//$min_documentRoot = $_SERVER['SUBDOMAIN_DOCUMENT_ROOT'];
//當$min_documentRoot為空時,其值就是$_SERVER['DOCUMENT_ROOT'],
//但合並的文件不在$_SERVER['DOCUMENT_ROOT']下,會導致400錯誤,
//這個時候可以啟用第2行或第3行
4. 配置Minify,即編輯min/config.php文件
$min_enableBuilder = true;
//本地使用時可以通過http://dwn/min/builder/來進行配置,外部使用時請設置為false
//$min_cachePath = 'c:WINDOWSTemp';
//$min_cachePath = '/tmp';
//$min_cachePath = preg_replace('/^d+;/', '', session_save_path());
//選擇其一,去掉注釋設置臨時緩存目錄,這樣可以減少程序運算提高性能
$min_serveOptions['maxAge'] = 1800;
//設置浏覽器緩存的時間,為了提升性能建議這個時間設置盡可能的長,比如315360000
//如果需要在不改變URL的情況下更新靜態文件,可以采用類似時間戳的方式,
//如http://localhost/min/f=example/example.css&20100601.css
//建議靜態文件采用版本號管理,每次修改都需要升級版本號,這樣就無需時間戳了
//如http://localhost/min/f=example/example_1_0_1.css
$min_serveOptions['minApp']['maxFiles'] = 10;
/