前一篇文章「壓縮網頁大小」是說明如何在網頁於輸出前進行檔案的GZip壓縮,
而現在要來說明如何去針對頁面中所使用的Javascript與CSS進行壓縮。
其實對Javascript與CSS的優化有很多種,使用YSlow或是PageSpeed對網頁進行分析,也會有特別針對這兩種檔案的建議。
YSlow的分析建議,抓出了很多未經過壓縮處理的js、css檔案…..抓出一個就會扣3分…
這個項目有這麼多個沒有進行處理,所以此項目只有F。
分析項目也會告訴你,進行壓縮處理能有什麼樣的好處,說明裡有強調如果進行壓縮會降低約70%的大小。
可以看到我的檔案的suffix都有個 compress或是compressed,
其實也不是經過GZip壓縮,而是利用YSlow所提供的工具連結,進行檔案的minify所以只是一個命名上的錯用。
工具中的連結,會導引你到網站中幫你網站所使用的js、css做些縮小化處理,
這邊也提供圖片的壓縮處理,它所壓縮過的檔案的確是會大大縮小你的圖片檔案大小,但卻不會對品質影響太大,相當值得推薦使用。
這邊告訴你使用YSlow提供的壓縮工具,可以節省多少的檔案大小。
PageSpeed也提出對於js、css檔案的壓縮建議。
PageSpeed也是有同樣的項目分析建議 ,並且也有提供最佳化的工具連結。
工具中的連結,會導引你到網站中幫你網站所使用的js、css做些縮小化處理,
PageSpeed也提供圖片的壓縮處理,它所壓縮過的檔案的確是會大大縮小你的圖片檔案大小,
卻不會對品質影響太大,相當值得推薦使用。
但是,上述的工具最多只提供你對js、css檔案做縮小化的功能,縮小化對於檔案大小的變化其實還是有限,
所以還是要用Gzip進行壓縮,才能達到我們要的目的,而網路上也有許多的工具可以幫助到我們處理這項工作,
進行壓縮前,看一下原本的檔案大小
看起來好像也沒有多少,但如果你的網站有一堆js、css檔案,然後每個都會有超過30KB以上,然後天天有成千上萬的人造訪…
其實想起來,對於網站的流量也算是個成本上的負擔,而且我的檔案還是經過最小化處理過。
圖中可以看到Server回應的Header內容,輸出的Javascript沒有做GZip處理
當然我們也是可以利用IIS的設定,去針對這些靜態檔案做Gzip的壓縮處理,
例如:應用 IIS 6.0 的 Gzip 壓縮功能降低網路傳輸量,這篇文章就有相當清楚的說明。
但如果你所使用的主機環境不允許你去做這些設定的時候呢?
(虛擬主機、許多系統共用主機而不允許中斷行為、其他原因)
此時就使用程式的方式來解決這個問題。
一般網路上會找到一些相關的文章,有的會用HttpHandler或是HttpModule來進行,
用這兩種方式的好處是,你只要寫好程式然後再到Web.Config中的這兩個區段去增加設定即可,
不過我這邊要用的是在Global.asax中去做處理,方式就如同「壓縮網頁大小」中的方式一樣。
From MSDN:
Global.asax http://msdn.microsoft.com/zh-tw/library/2027ewzw(v=VS.80).aspx
Global.asax 檔案 (又稱為 ASP.NET 應用程式檔案) 是一種選擇性 (Optional) 檔案, 其中包含用來回應 ASP.NET 或 HTTP 模組所引發之應用程式層級和工作階段 (Session) 層級事件 的程式碼。 Global.asax 檔案在 ASP.NET 應用程式的根目錄中。 在進行執行階段時,便會剖析 Global.asax,並將其編譯成動態產生的 .NET Framework 類別 (此類別衍生自HttpApplication 基底類別)。 ASP.NET 的設定會自動拒絕任何對於 Global.asax 檔案的直接 URL 要求,因此外部使用者無法 下載或檢視其中的程式碼。 |
HttpApplication 類別 http://msdn.microsoft.com/zh-tw/library/system.web.httpapplication(VS.80).aspx
定義 ASP.NET 應用程式內所有應用程式物件共用的方法、屬性和事件。 這個類別是使用者在 Global.asax 檔案裡為應用程式定義的基底類別。 HttpApplication 類別的執行個體是建立在 ASP.NET 基礎結構,而不是由使用者直接建立。 HttpApplication 類別的一個執行個體是用來處理存留期內的許多要求,但是一次只能處理一個。 因此,成員變數可以用來儲存每個要求的資料。 |
在「壓縮網頁大小」中對網頁進行Gzip壓縮,是在「HttpApplication.PreRequestHandlerExecute」事件中
「正好發生於 ASP.NET 開始執行事件處理常式 (例如,網頁或 XML Web Service) 之前。」
而要對js、css處理壓縮是要在「HttpApplication.PostReleaseRequestState 事件」
「當 ASP.NET 已完成執行所有要求事件處理常式並已儲存要求狀態資料時發生。」
就是要把壓縮的動作給延後到頁面Render之後去處理,js、css檔案是連結外面的檔案,
與aspx頁面本身的事件處理是比較沒有直接關係的。
PS.對於ASP.NET Application生命週期,可以參考MSDN的「ASP.NET 應用程式生命週期概觀」
Step1.
延續之前文章的程式,CompressUtils.cs
#region -- CompressCssAndJavascript --
/// <summary>
/// Compresses the CSS and javascript.
/// </summary>
/// <param name="app">The app.</param>
public static void CompressCssAndJavascript(HttpApplication app)
{
string contentType = app.Response.ContentType;
if (contentType == "text/css" || contentType == "application/x-javascript" || contentType == "text/javascript")
{
app.Response.Cache.VaryByHeaders["Accept-Encoding"] = true;
string acceptEncoding = app.Request.Headers["Accept-Encoding"];
if (acceptEncoding == null || acceptEncoding.Length == 0) return;
acceptEncoding = acceptEncoding.ToLower();
if (acceptEncoding.Contains("gzip"))
{
app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "gzip");
}
else if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
{
app.Response.Filter = new DeflateStream(app.Response.Filter, CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "deflate");
}
}
}
#endregion
針對 ContentType 為 “text/css””text/javascript””application/z-javascript”才進行壓縮處理
Step2.
在Global.asax中增加事件的處理
void Application_PostReleaseRequestState(object sender, EventArgs e)
{
CompressUtils.CompressCssAndJavascript(sender as HttpApplication);
}
來看看執行結果,
YSlow的「Compress components with gzip」此項已經沒有任何建議改進的檔案,分數也由之前的F變為A
PageSpeed也沒有對壓縮項目提出建議。
壓縮前
壓縮後
再來看看壓縮後的檔案狀況,可以看出的確是有達到壓縮的目的,
當然CSS檔案原本就很小,所以壓縮的效果比較不明顯(但還是有變小),
而javascript檔案可以明顯看出,由原本的18.2KB縮小到5.2KB,變為原來的1/3不到。
由檔案的Header內容也可以看到,檔案確實有經過gzip處理。
當然壓縮的程式碼還可以有改進的空間,例如:
可以不用每次Request進來就做一次壓縮,可以將壓縮過的內容給加入Cache中,減少此類靜態檔案的處理,也減少系統處理的負載。
將原本最小化(minify)的手動工作改由程式進行,減少設計人員的維護工作。
以下是參考的文章:
GZip compress your website's HTML/CSS/Script in code
Building a GZip JavaScript Resource Compression Module for ASP.NET以上
沒有留言:
張貼留言