2010年9月1日 星期三

ASP.NET Sprite and Image Optimization Framework介紹與使用

在YSlow Rules中,有關於Image的部份就提出了幾點效能上改進的建議,
http://developer.yahoo.com/performance/rules.html#opt_images
  1. Optimize Images
  2. Optimize CSS Sprite
  3. Don’t Scale Images in HTML
  4. Make favicon.ico Small and Cacheable
而所謂提高網頁效率的14條準則中的第一條就是「Make Fewer HTTP Requests」,
盡可能的減少Client端對Server端的HTTP 請求數。



來看看一個例子。
image
由上圖中的YSlow檢測結果可以看到,第一條的建議中就有針對背景圖片的建議,
而YSlow的建議是,試著將這些圖片給組合起來,然後用CSS Sprites方式來顯示圖片。
一堆的HTTP Request!!
image

其實這也就是「用一張組合好的大圖取代網頁中多個小圖」
將許多的小圖片組合成一張大圖片,讀取一次後,利用CSS制定每個小圖的位置(background-position 屬性)
於網頁中使用制定好的CSS做圖片的顯示。
只花一次的讀取成本以及事先制定好的CSS,來換取多個小圖所造成的HTTP Request成本。

網路上也有相當多現成的CSS Sprites製作工具,如下面連結的網站,
CSS SPRITES GENERATOR http://csssprites.com/
CSS Sprite Generator http://tw.spritegen.website-performance.org/

相關的介紹與連結
CSS Sprites: What They Are, Why They are Cool, and How To Use Them
CSS Sprites 產生器,改造網頁以加快圖示載入速度
Google首頁的CSS Sprite
把愛放生 - CSS Sprites
Will 保哥 - 使用 CSS Sprites 設計網頁但不用 background-image 的技巧

但是一般的程式設計師很少會去管設計面的相關事務,舉凡頁面的設計、圖片製作、版面編排等,都會由專業的網頁設計師來做,
當然很多的網頁設計師會使用CSS Sprite技術,
但是如果有碰到IE6、沒想到、沒聽過、版已經切了現在才講、用這個還要另外處理CSS等等等的問題時,
通常「先求有、再求好」「東西有出來就好」等論調就會出現,
當然~這也是沒辦法的事情,時程已經快到了,什麼網頁效率的考量都只能當做空談。

尤其是對程式設計師來說,一般簡單的CSS操作…可以,但是再進階一些的操作呢?……就一定會舉起雙手投降,
至少就我來說,就是這樣。

如果說一個已經做好切版的設計然到就沒有辦法改善了嗎?(除非你給網頁設計師好處然後請他重做一次)
不過這問題看來似乎可以用程式的方式來解他!
在2010-08-05的時候,ASP.NET有發佈了一個技術,用簡單並且快速的方式來解決這個問題。

image
Sprite and Image Optimization Framework
http://aspnet.codeplex.com/releases/view/50140
Release Notes
The ASP.NET Sprite Control and framework is designed to decrease the amount of time required to request and display a page from a web server by performing a variety of optimizations on the page’s images.

相關影片介紹
ASP.NET Sprite & Image Optimization Framework Intro in WebForms
http://weblogs.asp.net/craigshoemaker/archive/2010/08/06/asp-net-sprite-amp-image-optimization-framework-intro-in-webforms.aspx

在說明如何使用之前:
目前Release的版本(2010-08-05)只能支援 .NET Framework 4.0,對於ASP.NET WebForm 或是 ASP.NET MVC 2都有支援。
目前此功能的開發狀態還只是:Beta!

步驟一:

先從網站上將 Sprite and Image Optimization Framework 下載,
下載之後的文檔是一個壓縮檔案,
image
壓縮檔內有兩個Sample網站專案,
分別是ASP.NET WebForm「WebFormsControlSample」
以及ASP.NET MVC2「MVC Helper Sample」,
另外還有一個主要的API專案「ImageOptimizationFramework」
一個WebForm 的WebControl專案「ImageExControl」
一個MVC Helper專案「MVC Helper」

方案內容
image


步驟二:

我們開啟一個新專案並引用參考「Sprite and Image Optimization Framework」,
注意!目前Release版本只有支援.NET Framework 4.0,無法支援之前的版本,
不過作者於未來的版本有打算支援 .NET Framework 3.5

Features under consideration for future releases:
  • Automatically selecting the most efficient sprite background colour
  • Automatically minifying the rendered CSS
  • Compiling against .NET 3.5

如果是使用WebForm,建議直接引用「WebFormsControlSample」內Bin\Debug目錄的檔案
ImageOptimizationFramework.dll, ImageSprite.dll
image

如果是使用MVC,則建議引用「MVC Helper Sample」內Bin\Debug目錄的檔案
ImageOptimizationFramework.dll, ImageSprite.dll
image

注意!WebForm與MVC的ImageSprite,兩者是完全不同的內容,一個是WebContro而另一個是MvcHelper!要分清楚!

WebForm專案的引用
image

MVC專案的引用
image


步驟三:

加入參考之後,不論是WebForm或是MVC,
於Web.Config檔案要添加以下的設定
IIS 6.0
在 system.web 的 httpModules 下要加入
<add type="Microsoft.Samples.Web.ImageOptimizationModule" name="Microsoft.Samples.Web.ImageOptimizationModule"/>
image
IIS 7.0
在 system.webServer 的 modules下要加入
<add type="Microsoft.Samples.Web.ImageOptimizationModule" name="Microsoft.Samples.Web.ImageOptimizationModule"/>
image


步驟四:

(WebForm與MVC皆同)
於網站專案中建立一個名為「App_Sprites」的目錄,
這個目錄名稱是固定的(目前的Release版本無支援其他自定的目錄名稱,不過作者是打算以後的版本做支援)
在「App_Sprites」下就建立子目錄,各個子目錄放置系統所需要用到的圖檔(PNG),
子目錄沒有限制數量,而圖檔也不限制數量。
此Framework可以接受的圖像格式有:"*.jpg", "*.gif", "*.png", "*.bmp", "*.jpeg"
image

 


步驟五:

WebForm
於Default.aspx(看你是要用在哪個頁面)原始檔中,
在的下面添加WebControl的註冊
<%@ Register TagPrefix="asp" Namespace="Microsoft.Samples.Web" Assembly="ImageSprite" %>
image
這個在WebForm的專案中,有使用到Css Image Sprite的頁面一定要加上去。
而頁面中使用CSS Sprite Image則是如以下的方式
<asp:ImageSprite ID="ImageSprite1" runat="server" ImageUrl="~/App_Sprites/icons/add.png" />
image
  MVC   在頁面中用以下的方式做圖片的顯示輸出
<%: Microsoft.Samples.Web.ImageSprite.Image("~/App_Sprites/Sweetie/24-heart-gold.png")%>
image
View/Home/Index.aspx
可以看到無論是用WebForm還是MVC,設計階段的頁面原始碼中取用圖片還是直接指向圖片的路徑位置。
到這邊還沒有看到任何指定css檔案與合併個別檔案組成一個css-sprite png的步驟,直接執行專案就可以看到效果。


步驟六:

F5 執行

WebForm

image

在WebForm的執行頁面原始碼,其中一個圖片的HTML Tag
頁面就幫我們的圖片輸出為這樣的格式 
<img id="ImageSprite1" class="icons_add-png"src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="border-width:0px;" />
image

而CSS的使用
<link href="App_Sprites/icons/lowCompat.css" rel="stylesheet" type="text/css" media="all" />
程式就幫我們自動產出這一段,這是因為在頁面中有使用到ImageSprite的控制項,所以就會自動產生上面的CSS檔案引用。
image

以Firefox/ForeBug觀察「網路」項目
image
image
上圖可以看到,除了Default.aspx外,另外一個下載的文件檔案就是highCompat.css

highCompat.css/lowCompat.css為自動生成的CSS文件 這兩個CSS文件暫沒有不同,但是在我的試做過程中,IE會使用 lowCompat.css而Forefox則會使用highCompat.css

MVC

image
CSS檔案的引用以及圖片顯示的HTML Tag
<link href="App_Sprites/Sweetie/lowCompat.css" media="all" rel="stylesheet" type="text/css" /> 
... 
... 
<img class="Sweetie_24-heart-gold-png"src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
image

看看輸出的HTML Tag,圖片使用的屬性可以看出一些端倪,class名稱原則上就是指定的圖片位置與檔案,
<img id="ImageSprite1" class="icons_add-png" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="border-width:0px;" />
folderName_ImageName-ExtensionName
而src就是經過base64處理的圖片內容,這時候就要看lowComopat.css檔案

在我們執行專案的時候,Framework就會自動去執行合成圖片產生sprite0.png,並且產出兩個 css檔案,
分別是 highCompat.css、lowCompat.css
(如果看不到的話,請使用方案總管上面的顯示全部檔案,就可以看到Framework自動產生的檔案, 看不到是因為這些檔案尚未加入專案之中)
此外還會自動產出 sprite0.png(合併的大圖)、timeStamp.dat(自動產出檔案的時間戳記)
image

來看看合併的sprite0.png圖檔內容,這個圖檔的檔案大小約1.17KB
image
image

而組合在一起的個別檔案的大小為 2.14 KB,
可以看到合併為一個圖檔有把檔案大小給縮小了些。
 image


步驟七:

看到上面落落長的說明,應該有人會想說,Framework都已經自動將小圖給合併為一個大圖檔,
為何在兩個自動產生的CSS檔案中,還會將圖檔用base64編碼的方式給存放在highCompat.css中呢?
image

在文件中有提到幾點說明

· Browser support. Image inlining is not supported by several popular browsers, including Internet Explorer 8 and earlier versions, and Firefox versions lower than 3.5.

· Larger image sizes. When an image is converted to base-64 encoding, its size is increased, up to about 40% larger than the original size.

· Duplication. Images that are repeated across several pages (such as those for interfaces) will be stored once per page instance, rather than in a single location on disk. This can cause storage bloat and makes updating these images almost impossible.

· Caching. Web browsers do not cache base-64 encoded images If they are encoded directly into HTML. (However they will cache them if the images are stored in a CSS style sheet.)

其實我們也可以自定最佳化的設定,告訴Framework該如何做檔案的合併處理
以下是設定檔的XML格式內容,而XML檔名則必須為「settings.xml」
<?xml version="1.0" encoding="utf-8"?>
<ImageOptimizationSettings>
<FileFormat>png</FileFormat>
<Base64Encoding>true</Base64Encoding>
<Quality>80</Quality>
<BackgroundColor>00000000</BackgroundColor>
<MaxSize>500</MaxSize>
</ImageOptimizationSettings>
· FileFormat. 合併檔案的圖檔格式(JPG, GIF, PNG 或是 BMP)
· Quality. 合併後的圖檔品質(百分比)
· MaxSize. 合併檔案的最大檔案大小,如果合併的圖檔大小超過設定值,則會再生成另外一張圖檔 sprite1.png
· BackgroundColor. 合併圖檔的背景色.預設為透明,設定的格式為Standard ARGB Format
· Base64Encoding. 圖片是否啟用base64編碼格式生成inline images,就是生成上面CSS中那長長的一串文字編碼

用Firefox/FioreBug來觀察就容易了解
image

如果settings.xml的Base64Encoding項目設定為false的話,則不會生成base64 inline inages,而將會直接使用生成的sprite0.png
例如:
<?xml version="1.0" encoding="utf-8"?>
<ImageOptimizationSettings>
<FileFormat>png</FileFormat>
<Base64Encoding>false</Base64Encoding>
<Quality>80</Quality>
<BackgroundColor>00000000</BackgroundColor>
<MaxSize>500</MaxSize>
</ImageOptimizationSettings>

專案執行後,此時就會載入sprite0.png
image


而原本hignCompat.css中,base64 inline-image的部份也改為使用bcakground-image:url(sprite0.png)
以及用background-position來決定圖片位置以作為顯示。
image

沒有加入 settings.xml 時,Framework會自動產生 lowCompat.css 與 highCompat.css,而 highCompat.css 則是會預設使用 base64 inline images.
lowCompat.css,這是給無法使用或無支援inline images的瀏覽器使用。
highCompat.css,如果有支援inline images的瀏覽器使用。

這邊引用原始文件的一張圖,來說明個瀏覽器版本支援CSS inlining以及Sprites的能力
image

PS.
如果<Base64Encoding>為True,是可以使用「ASP.NET對Javascript與CSS檔案進行壓縮」方法,
可以對CSS檔案壓縮,而且不影響圖片的顯示。

沒有使用壓縮方法
image

有使用壓縮方法後
image


以上就是說明有關「Sprite and Image Optimization Framework」的內容與使用說明,以程式的方式來達成CSS Sprite的效果,
除了可以提昇網頁輸出效能外,也可以減少伺服器的負擔,只可惜的是,目前此Framework應當是尚未支援.NET 4.0之前的版本,
不過至少我們知道除了要麻煩網頁設計師幫我們之外,程式設計師也可以自己搞定CSS Sprite!

建議:

網站專案必須是使用 .NET Framework 4.0 或是 ASP.NET MVC2

一定要下載「Documentation」,文件不大,2MB多,也才16頁,但是卻有相當清楚的說明。

而Sample Site Documetation則是Sample網站的圖示說明,如下所示:
image

由於寫得相當雜亂,如有未盡詳細之處或是有錯誤的地方,請提出指正,謝謝

相關連結整理:
Sprite and Image Optimization Framework
http://aspnet.codeplex.com/releases/view/50140

Sprite and Image Optimization Framework & DotNetNuke

http://weblogs.asp.net/rchartier/archive/2010/08/09/sprite-and-image-optimization-framework-amp-dotnetnuke.aspx

相關影片介紹
ASP.NET Sprite & Image Optimization Framework Intro in WebForms
http://weblogs.asp.net/craigshoemaker/archive/2010/08/06/asp-net-sprite-amp-image-optimization-framework-intro-in-webforms.aspx

對岸博客園也有一篇相同主題的文章:
重典的博客 - 在ASP.NET中自动合并小图片并使用CSS Sprite显示出来

以上



沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。