demoshop

demo, trying to be the best_

版本
Preview 4

網站最佳化技巧中有一種稱為「CSS Sprite」的技巧,主要原理是減少瀏覽器和伺服器端的訪問,並且利用瀏覽器本身的快取機制達到優化的效果,以往「CSS Sprite」需要設計人員協助處理,但是現在利用 Sprite and Image Optimization 就可以達到自動產生,立即優化的效果!怎麼辦到呢?繼續看下去吧。

筆者無法在這裡詳細說明前端網頁效能瓶頸的點在哪裡,所以有寫一篇前置文章【線上測速工具 WebPagetest 馬上得知網站效能瓶頸】利用工具簡單快速的讓前端開發人員瞭解目前網站的瓶頸,不過對於完全沒有前端網頁最佳化相關知識的朋友,可能會不瞭解這樣做的意義。因此推薦《高效能網站建置指南 (Even Faster Web Sites: Performance Best Practices for Web Developers)》這本很有名的書籍,雖然內容有極少部分不太適合現在網頁的新技術,但大多數的觀念與技巧還是相當受用,有興趣的朋友可以購買觀看。


筆者經常提到所有網站最佳化的技術中針對「圖片」下手是最有效益的,因為圖片往往是整個網站中容量最大數量最多的元素,之前有介紹過圖片的容量最佳化的套件「Visual Studio 利用 Image Optimizer 套件快速最佳化專案圖片」這是要介紹的是將圖片合併的套件 Sprite and Image Optimization ,雖然 Sprite and Image Optimization 同時支援 ASP.NET Web Form 與 ASP.NET MVC 但是本篇文章會使用 ASP.NET MVC 做示範。


現在所有的套件都會從 NuGet 開始,這個也不例外,請建立好 ASP.NET MVC 專案後選擇「管理 NuGet 套件」


請在搜尋的地方輸入「aspnetsprites」

注意事項本範例使用 MVC 所以選擇MVC用的套件,如果讀者使用 WebForm 請自行選擇 WebForm 專用的套件。


套件安裝完畢後在專案下會多出「App_Sprites」資料夾


請將要使用 CSS Sprite 的圖片放置「App_Sprites」資料夾,本範例刻意使用了三種尺寸不同的圖片

注意事項CSS Sprite 技巧應該使用在小圖示上,請不要把所有圖都放進去,這是不明智的行為。


圖片都放進「App_Sprites」資料夾後請執行你的網站


只要執行過網站後就可以回到 Visual Studio,請點選方案總管上的「重新整理」「顯示所有檔案」


「App_Sprites」資料夾增加了許多尚未加入專案的檔案


其中「sprite0.png」就是所有圖片合併後的大圖


開啟「_Layout.cshtml」檔案,增加以下內容

@using Microsoft.Web.Samples
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>@ViewBag.Title - 我的 ASP.NET MVC 應用程式</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width" />
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    @Sprite.ImportStylesheet("~/App_Sprites/")
</head>
<body>
    <header>
        <div class="content-wrapper">
            <div class="float-left">
                <p class="site-title">@Html.ActionLink("您標誌的位置", "Index", "Home")</p>
            </div>
            <div class="float-right">
                <section id="login">
                    @Html.Partial("_LoginPartial")
                </section>
                <nav>
                    <ul id="menu">
                        <li>@Html.ActionLink("首頁", "Index", "Home")</li>
                        <li>@Html.ActionLink("關於", "About", "Home")</li>
                        <li>@Html.ActionLink("連絡", "Contact", "Home")</li>
                    </ul>
                </nav>
            </div>
        </div>
    </header>
    <div id="body">
        @RenderSection("featured", required: false)
        <section class="content-wrapper main-content clear-fix">
            @Sprite.Image("~/App_Sprites/twMVC-180_100.png")
            @Sprite.Image("~/App_Sprites/forum_a.jpg")
            @Sprite.Image("~/App_Sprites/content_36.png")
            @RenderBody()
        </section>
    </div>
    <footer>
        <div class="content-wrapper">
            <div class="float-left">
                <p>&copy; @DateTime.Now.Year - 我的 ASP.NET MVC 應用程式</p>
            </div>
        </div>
    </footer>

    @Scripts.Render("~/bundles/jquery")
    @RenderSection("scripts", required: false)
</body>
</html>

程式碼說明如下:

  • 第一行這是此套件的命名空間(preview 的東西命名空間比較怪 XD)
  • 第十二行使用套件提供的 HTML Helper 載入CSS檔案
  • 37~39是使用套件提供的 HTML Helper 載入圖片(圖片名稱並未變動)

回到瀏覽器來看效果,本範例使用 Firefox 開啟

依據上圖可以看到圖片的確是一張一張的(請看HTML碼)而且使用了 BASE64 的方式

注意事項圖片使用 BASE64 的好處是瀏覽器在載入的時候就已經得到圖片,不需要再去和伺服器要,進而降低 DNS 查詢往返時間,但是老舊的瀏覽器是無法支援 BASE64 圖檔的,不過此套件很聰明會自動判斷,以下繼續來看範例。

 

假設今天使用的是 IE7 這種多年前的瀏覽器來開啟網站,就可以看到圖片載入的方式的確就是使用 CSS Sprite 技巧了

可以這樣自動判斷主要原因是剛剛載入 CSS 的時候是使用套件提供的 Helper ,此套件會產生兩種 CSS 應用於這兩種不同的情況


雖然此套件可以自行判斷瀏覽器是否支援 BASE64 圖檔來決定如何產生,但 BASE64 的方式其實並不適合,因為減少與伺服器端往返的時間代價是圖片將再也無法被快取,瀏覽器的快取機制在網頁最佳化中扮演很重要的角色,利用了快取機制瀏覽器會知道圖片在本機就有了不用和伺服器拿,顯示速度會更快,因此使用 BASE64 其實不是一個好方法,要強制套件都使用 CSS Sprite 技巧,請將剛剛載入 CSS 的方式改為直接明確指定。

<link href="~/App_Sprites/lowCompat.css" rel="stylesheet" />

這樣子即使是支援 BASE64 的瀏覽器也是使用 CSS Sprite 了。

 

好了,這是最後一段的廢言,看了上面的解說,讀者是否覺得這技巧十分簡單又實用呢?在最後還是要提醒各位,此套件為 Preview 4 所以實際使用上會發生什麼問題還不知道,請各位謹慎評估哩(筆者的專案有在使用目前尚未發現問題)

 

注意事項如果你的圖片更新了套件也會自動重新合併圖片,主要是靠 timeStamp.dat 這個檔案處理的,只要點開就知道他做了什麼事。
 

系列文章

回應討論