使用 CSS sprite 的好處和壞處
原文:CSS Sprites: Useful Technique, or Potential Nuisance?
譯文:CSS Sprites:魚翅還是三鹿?
無處不在的 CSS sptites - 為數不多的幾個可以直接跳過”流行”這個過程,而可以馬上并且牢牢地躋身于最佳 CSS 實踐之中的幾個技術之一。雖然它真正流行是在 A List Apart解釋并認可這個技術之后,但是早在 2003 年 7 月份,Peter Stanicek 就已經開始談論它了。
目前大多數的開發人員對這個技術都有相當地掌握,也有很多關于它的教程和文章。幾乎所有的文章中都宣稱設計師和開發人員都應該使用 CSS sprite 來減少 HTTP 請求數,并且節省一些流量。這個技術被大量網站使用,包括使用了大型 sprite 的 Amazon .
但是這些被廣泛熱議的好處真的是值得的嗎?設計師們是否在沒有全面考慮到所有情況的情況下,在盲目地使用這個技術呢?設計師們是不是過于關注 CSS sprite 的流行,而忽略了其它應該仔細斟酌的因素了呢? 這篇文章會討論下使用 CSS sprite 的好處和壞處,尤其關注”濫用” sprites 的情況,而且會解釋下為什么“濫用” sprite 其實是浪費時間。
瀏覽器緩存所有圖片
sprite 技術的其中一個好處是圖片的加載時間(在有許多 sprite 時,單張圖片的加載時間)。由所需圖片拼成的一張 GIF 圖片的尺寸會明顯小于所有圖片拼合前的大小。單張的 GIF 只有相關的一個色表,而單獨分割的每一張 GIF 都有自己的一個色表,這就增加了總體的大小。因此,單獨的一張 JPEG 或者 PNG sprite 在大小上非常可能比把一張圖分成多張得來的圖片總尺寸小。但是這真的有想象的那么好嗎?
一般來說,瀏覽器會緩存所有的圖片 – 無論圖片 sprite 與否。sprite 技術只是在頁面第一次加載的時候才會節省帶寬,同時緩存也會對使用相同圖片的其他頁面有效。
Firefox 緩存顯示的瀏覽器緩存的來自 amazon.com 的圖片(在 Firefox 地址欄輸入 “about:cache” 來查看)。
考慮到現在的普遍網速已經比 2003-2004 年時提出這個技術的時候要快多了,因此大量使用 sprite 技術就不是那么必要了。有一點需要明確,不是說不應該用 sprite,而是不應該為了有限的好處來濫用這個技術。
拼合圖片的時間成本會增加
想象一下一個有三個狀態的圖片按鈕是怎么制作的:代表不同的狀態的圖片需要臨近放置在一起組成一張圖片。在使用 Photoshop 或其他軟件切圖時,不同的狀態并不會在一起;需要把他們單獨切出來再合并為一張圖片。
如果其中任一個圖片狀態需要改變,整個圖片就需要重新制作保存。對一些設計師來說這不是什么問題,也許他們會單獨保留不同按鈕狀態的源文件,這樣需要合并的時候就簡單了。但是這個過程有點復雜,遠沒有切出一個單獨圖片來的簡單。
為了節省幾 k 的流量和幾個服務器請求(還只發生在第一次加載頁面時),sprite 技術是否真的值得?
編碼和維護的時間成本會增加
圖片切片輸出之后,麻煩依然存在。雖然習慣這個過程之后,按鈕 sprite 可以很簡單地編碼到 CSS 中,但是其他的 sprites 就不這么簡單了。
單一的一個按鈕一般會是個有定寬的 <ul> 元素。假如按鈕的 sprite 是彼此獨立的,就比較簡單:<ul> 的寬高會和列表項和錨點的寬高一致,每個狀態的 sprite 對齊擺放。sprite 的位置也可以很容易地根據每個按鈕的寬高計算出來。
但是遇到之前提到的,像 Amazon 或者Google 用到的大型 sprite 的情況時,會怎么樣呢?你能想象到到維護這么一個文件,并且在 CSS 中改變 sprite 項的位置會是什么樣嗎?還有第一次創建 CSS 代碼的情況?相對于一個可以輕松計算出來狀態位置的簡單按鈕來說,大型的 sprite 會導致無盡地測試和圖片狀態的重新擺放。
一些用于定位 Google 的 sprite 圖片的樣式
Amazon 的 sprites 確實節省了至少 30 個 HTTP 連接,性能方面也確實有了很大的提高。但是把這些好處拿來和開發以及維護成本做個比較,再把緩存和網速等因素考慮進來,決定使用如此大型的 sprites 也許就不那么令人信服了。
Sprites 是否真的需要“維護”?
當然了,有些人不覺得 sprite 是首要引起頭疼的問題。大部分情況下,一個 sprite 創建并編碼完之后,就很少會被改動了,也不會受進行中的網站維護的影響。假如你感覺 sprite 維護不是個問題的話,那么也許使用大型 sprite 是最好的選擇。
不是所有圖片都是背景
另一個不提倡濫用 CSS sprite 的理由是這會導致開發人員錯誤地使用背景圖片。有經驗的開發人員會在項目中考慮可訪問性問題,他們明白并不是每個圖片都是背景。背景圖片應該留給按鈕以及用來裝飾元素,而用來傳達重要信息的圖像應該內聯在 XHTML 中。
Amazon 正確是使用了內聯圖像元素和裝飾用的背景。
錯誤得使用 Sprites 影響可訪問性
一些剛入門的開發人員會為了節省 HTTP 請求數(這是使用 CSS Sprite 一直強調的好處)而把所有的圖片都當背景圖片來處理 – 甚至是那些傳達重要信息的圖片。結果會導致一個缺乏可訪問性的網站,也會降低 HTML 中 title 和 alt 的潛在益處。
因此,CSS sprite 本身沒錯,而且也不會引發可訪問性問題(事實上,正確得使用會提高可訪問性)。但是不分對錯得過度使用 sprite 會阻礙具有可訪問性和生產率方面的網頁建設進程。
HTTP 請求數又如何?
許多人會據理力爭,改善網站性能最重要的部分就是減少 HTTP 請求數。也要知道一項研究表明一個網站日常的訪問者中 40-60% 比例都是沒有瀏覽器緩存的。這是否足以說明應該在所有情況下使用大型 sprites 呢?或許是這樣。尤其是考慮到用戶的首次來訪對一個網站的重要性。
Firefox 的 YSlow 插件顯示 HTTP 請求數
以往的瀏覽器一般只允許 2 個并發 HTTP 連接,3.0 版本以來的 Firefox 和 IE8 默認允許 6 個并發 HTTP 連接。這意味著每臺服務器有 6 個并發連接。引用 Steve Souders 的話:
“明白這是服務器的基礎是很重要的。使用多個域名,如 1.mydomain.com, 2.mydomain.com, 3.mydomain.com, 等等,使開發人員可以完全利用服務器連接數。在所有域名是同一 IP 地址的 CNAME 時依然有效。”
因此,或許在按鈕狀態之外使用 CSS sprites 也是有益的,在未來,隨著網絡連接速度的加快和新版瀏覽器的性能提升,使用大型 sprites 所帶來的好處將會變得不值一提。
那些 Sprites 生成器呢?
另一個喜愛大型 sprite 的理由是可以利用一些sprite 生成器來簡單得生成 sprite。對此類工具的詳細討論和評測不在本文討論范圍。但是從作者對此類工具的研究來看,幫助非常有限,并且維護這些 sprites 一樣需要可觀的工作量,這也是需要和收益權衡的。
有些工具,例如來自 Fondue 項目的這個,提供輸出 CSS 選項。Steve Souders’ 的工具SpriteMe 是另一個提供 CSS 編碼選項的。SpriteMe 會把現有的網站背景圖片轉換成單張 sprite 圖片(我之前提到的“大型” sprite)并提供下載以供編碼入頁面之中。然而這些工具只是有助于創建 sprite,并不能在維護方面提供多少幫助。Souder 的工具貌似對重新設計或布局的網站無效,而且只對那些現有的沒有使用 sprite 方法的網站有用。
可以改進現有的工具,而且未來也會有新的工具出現。但是,鑒于以上提到的這些缺點,是否還存在這種可能,就是開發人員依然把精力集中在有限的所得上?
關注多個性能提升點
上面提到,HTTP 請求數是提升網站性能需要考慮的一個非常重要的因素。但是有別的方法可以減少連接數,包括合并腳本和樣式表,使用遠程庫文件(即使用 Google 或者 Yahoo!提供的庫文件托管)。
除了 HTTP 請求數之外還有很多開發人員可以關注的用于提升網站性能的因素。包括服務器啟用 Gzip,正確的放置外鏈腳本,優化 CSS 語法,壓縮較大的JavaScript 文件,提升 Ajax 性能,避免使用已知的會引起性能問題的JavaScript 語法,等等。
YSlow 顯示了 HTTP 請求數之外可以提升網站性能的因素
如果開發人員花點時間來考慮下所有可以提升網站性能的因素,再權衡下利弊,也許就有較好的理由可以避免濫用 CSS sprite 了,并且會把精力放在那些物有所值的方面。
總結
請不要誤解我所說的。許多頂級的 blogger 和開發人員已經稱頌 sprite 的好處很多年了,最近幾年又把這些意見推廣到使用大型 sprite 上來了 – 因此應該認真得考慮下這些觀點。但是,這種有著完善的體制和系統,使得網站維護任務簡化并流水化的公司,并不是所有人都能進去的。大多數人都是獨立工作,或者接受別人創建的項目。這類情況下,大型的 sprite 會導致得不償失的麻煩。
糖伴西紅柿的總結
標題有點醒目 :) 原標題的規矩翻譯為 CSS Sprites:有用的技術還是潛在的麻煩?
關于 CSS Sprite,在Web 標準交流會 第二期的時候討論過。其實 CSS Sprite 是很有用處的。但是前提是不要超出一個度的限制。基本上很多問題最終都會歸于如何適度地使用的問題。老話說:過猶不及,其實還是很有道理的。
對于減少 HTTP 請求數問題,可以稍作妥協,把圖片分類,盡量把內容固定、后期不會有太多變動的圖歸入一個 sprite 中,例如一些 icon 。那些會經常改動的圖片歸入一類,分成幾組 sprite。對于設計花哨而生命周期很短的專題來說,真得,花費在拼圖上的時間和經歷實在是有點浪費了。
關于老外的文章,我現在覺得有些絮叨了。或許很多人也會有這個感覺。其實應該反思下,據說日本有專門的小冊子來教人做一些非常基礎的東西,內容步驟細致到令人發指得地步。基礎的東西大多人會不屑一顧,覺得別人都談論奇技淫巧、高級應用了,我還在搞這些基礎,多丟人啊。
基礎的東西其實沒那么簡單的,有誰能真得掌握了這些看上去簡單的基礎呢?看一下這個基礎問題你真的了解HTML嗎?
曾經有一個高手送我一本書,他寫了 ”Back to basic“ 送我,我在這里送給大家,希望大家都能踏踏實實地努力進步。
Tag: 設計公司 | 網頁設計公司 | 廣告公司 | 網站設計 | 平面設計 | 互動媒體 | 網頁設計 | Web design | Website design | design house | 媒體公司 | Iphone app | 程式設計 | Flash 網頁 | Flash game | 動畫設計 | 後期製作 | 網上商店 | 網上宣傳 | 網頁服務 |