使用CSS sprite 的好處和壞處分析
原文:CSS Sprites: Useful Technique, or Potential Nuisance?
無處不在的 CSS sptites - 為數(shù)不多的幾個(gè)可以直接跳過”流行”這個(gè)過程,而可以馬上并且牢牢地躋身于最佳 CSS 實(shí)踐之中的幾個(gè)技術(shù)之一。雖然它真正流行是在 A List Apart 解釋并認(rèn)可這個(gè)技術(shù)之后,但是早在 2003 年 7 月份,Peter Stanicek 就已經(jīng)開始談?wù)?/font>它了。
目前大多數(shù)的開發(fā)人員對這個(gè)技術(shù)都有相當(dāng)?shù)卣莆?,也有很多關(guān)于它的教程和文章。幾乎所有的文章中都宣稱設(shè)計(jì)師和開發(fā)人員都應(yīng)該使用 CSS sprite 來減少 HTTP 請求數(shù),并且節(jié)省一些流量。這個(gè)技術(shù)被大量網(wǎng)站使用,包括使用了大型 sprite 的 Amazon .
但是這些被廣泛熱議的好處真的是值得的嗎?設(shè)計(jì)師們是否在沒有全面考慮到所有情況的情況下,在盲目地使用這個(gè)技術(shù)呢?設(shè)計(jì)師們是不是過于關(guān)注 CSS sprite 的流行,而忽略了其它應(yīng)該仔細(xì)斟酌的因素了呢? 這篇文章會討論下使用 CSS sprite 的好處和壞處,尤其關(guān)注”濫用” sprites 的情況,而且會解釋下為什么“濫用” sprite 其實(shí)是浪費(fèi)時(shí)間。
瀏覽器緩存所有圖片
sprite 技術(shù)的其中一個(gè)好處是圖片的加載時(shí)間(在有許多 sprite 時(shí),單張圖片的加載時(shí)間)。由所需圖片拼成的一張 GIF 圖片的尺寸會明顯小于所有圖片拼合前的大小。單張的 GIF 只有相關(guān)的一個(gè)色表,而單獨(dú)分割的每一張 GIF 都有自己的一個(gè)色表,這就增加了總體的大小。因此,單獨(dú)的一張 JPEG 或者 PNG sprite 在大小上非??赡鼙劝岩粡垐D分成多張得來的圖片總尺寸小。但是這真的有想象的那么好嗎?
一般來說,瀏覽器會緩存所有的圖片 – 無論圖片 sprite 與否。sprite 技術(shù)只是在頁面第一次加載的時(shí)候才會節(jié)省帶寬,同時(shí)緩存也會對使用相同圖片的其他頁面有效。

Firefox 緩存顯示的瀏覽器緩存的來自 amazon.com 的圖片(在 Firefox 地址欄輸入 “about:cache” 來查看)。
考慮到現(xiàn)在的普遍網(wǎng)速已經(jīng)比 2003-2004 年時(shí)提出這個(gè)技術(shù)的時(shí)候要快多了,因此大量使用 sprite 技術(shù)就不是那么必要了。有一點(diǎn)需要明確,不是說不應(yīng)該用 sprite,而是不應(yīng)該為了有限的好處來濫用這個(gè)技術(shù)。
拼合圖片的時(shí)間成本會增加
想象一下一個(gè)有三個(gè)狀態(tài)的圖片按鈕是怎么制作的:代表不同的狀態(tài)的圖片需要臨近放置在一起組成一張圖片。在使用 Photoshop 或其他軟件切圖時(shí),不同的狀態(tài)并不會在一起;需要把他們單獨(dú)切出來再合并為一張圖片。
如果其中任一個(gè)圖片狀態(tài)需要改變,整個(gè)圖片就需要重新制作保存。對一些設(shè)計(jì)師來說這不是什么問題,也許他們會單獨(dú)保留不同按鈕狀態(tài)的源文件,這樣需要合并的時(shí)候就簡單了。但是這個(gè)過程有點(diǎn)復(fù)雜,遠(yuǎn)沒有切出一個(gè)單獨(dú)圖片來的簡單。
為了節(jié)省幾 k 的流量和幾個(gè)服務(wù)器請求(還只發(fā)生在第一次加載頁面時(shí)),sprite 技術(shù)是否真的值得?
編碼和維護(hù)的時(shí)間成本會增加
圖片切片輸出之后,麻煩依然存在。雖然習(xí)慣這個(gè)過程之后,按鈕 sprite 可以很簡單地編碼到 CSS 中,但是其他的 sprites 就不這么簡單了。
單一的一個(gè)按鈕一般會是個(gè)有定寬的 <ul> 元素。假如按鈕的 sprite 是彼此獨(dú)立的,就比較簡單:<ul> 的寬高會和列表項(xiàng)和錨點(diǎn)的寬高一致,每個(gè)狀態(tài)的 sprite 對齊擺放。sprite 的位置也可以很容易地根據(jù)每個(gè)按鈕的寬高計(jì)算出來。
但是遇到之前提到的,像 Amazon 或者 Google 用到的大型 sprite 的情況時(shí),會怎么樣呢?你能想象到到維護(hù)這么一個(gè)文件,并且在 CSS 中改變 sprite 項(xiàng)的位置會是什么樣嗎?還有第一次創(chuàng)建 CSS 代碼的情況?相對于一個(gè)可以輕松計(jì)算出來狀態(tài)位置的簡單按鈕來說,大型的 sprite 會導(dǎo)致無盡地測試和圖片狀態(tài)的重新擺放。

一些用于定位 Google 的 sprite 圖片的樣式
Amazon 的 sprites 確實(shí)節(jié)省了至少 30 個(gè) HTTP 連接,性能方面也確實(shí)有了很大的提高。但是把這些好處拿來和開發(fā)以及維護(hù)成本做個(gè)比較,再把緩存和網(wǎng)速等因素考慮進(jìn)來,決定使用如此大型的 sprites 也許就不那么令人信服了。
Sprites 是否真的需要“維護(hù)”?
當(dāng)然了,有些人不覺得 sprite 是首要引起頭疼的問題。大部分情況下,一個(gè) sprite 創(chuàng)建并編碼完之后,就很少會被改動(dòng)了,也不會受進(jìn)行中的網(wǎng)站維護(hù)的影響。假如你感覺 sprite 維護(hù)不是個(gè)問題的話,那么也許使用大型 sprite 是最好的選擇。
不是所有圖片都是背景
另一個(gè)不提倡濫用 CSS sprite 的理由是這會導(dǎo)致開發(fā)人員錯(cuò)誤地使用背景圖片。有經(jīng)驗(yàn)的開發(fā)人員會在項(xiàng)目中考慮可訪問性問題,他們明白并不是每個(gè)圖片都是背景。背景圖片應(yīng)該留給按鈕以及用來裝飾元素,而用來傳達(dá)重要信息的圖像應(yīng)該內(nèi)聯(lián)在 XHTML 中。

Amazon 正確是使用了內(nèi)聯(lián)圖像元素和裝飾用的背景。
錯(cuò)誤得使用 Sprites 影響可訪問性
一些剛?cè)腴T的開發(fā)人員會為了節(jié)省 HTTP 請求數(shù)(這是使用 CSS Sprite 一直強(qiáng)調(diào)的好處)而把所有的圖片都當(dāng)背景圖片來處理 – 甚至是那些傳達(dá)重要信息的圖片。結(jié)果會導(dǎo)致一個(gè)缺乏可訪問性的網(wǎng)站,也會降低 HTML 中 title 和 alt 的潛在益處。
因此,CSS sprite 本身沒錯(cuò),而且也不會引發(fā)可訪問性問題(事實(shí)上,正確得使用會提高可訪問性)。但是不分對錯(cuò)得過度使用 sprite 會阻礙具有可訪問性和生產(chǎn)率方面的網(wǎng)頁建設(shè)進(jìn)程。
HTTP 請求數(shù)又如何?
許多人會據(jù)理力爭,改善網(wǎng)站性能最重要的部分就是減少 HTTP 請求數(shù)。也要知道一項(xiàng)研究表明一個(gè)網(wǎng)站日常的訪問者中 40-60% 比例都是沒有瀏覽器緩存的。這是否足以說明應(yīng)該在所有情況下使用大型 sprites 呢?或許是這樣。尤其是考慮到用戶的首次來訪對一個(gè)網(wǎng)站的重要性。

Firefox 的 YSlow 插件顯示 HTTP 請求數(shù)
以往的瀏覽器一般只允許 2 個(gè)并發(fā) HTTP 連接,3.0 版本以來的 Firefox 和 IE8 默認(rèn)允許 6 個(gè)并發(fā) HTTP 連接。這意味著每臺服務(wù)器有 6 個(gè)并發(fā)連接。引用 Steve Souders 的話:
“明白這是服務(wù)器的基礎(chǔ)是很重要的。使用多個(gè)域名,如 1.mydomain.com, 2.mydomain.com, 3.mydomain.com, 等等,使開發(fā)人員可以完全利用服務(wù)器連接數(shù)。在所有域名是同一 IP 地址的 CNAME 時(shí)依然有效。”
因此,或許在按鈕狀態(tài)之外使用 CSS sprites 也是有益的,在未來,隨著網(wǎng)絡(luò)連接速度的加快和新版瀏覽器的性能提升,使用大型 sprites 所帶來的好處將會變得不值一提。
那些 Sprites 生成器呢?
另一個(gè)喜愛大型 sprite 的理由是可以利用一些 sprite 生成器來簡單得生成 sprite。對此類工具的詳細(xì)討論和評測不在本文討論范圍。但是從作者對此類工具的研究來看,幫助非常有限,并且維護(hù)這些 sprites 一樣需要可觀的工作量,這也是需要和收益權(quán)衡的。
有些工具,例如來自 Fondue 項(xiàng)目的這個(gè),提供輸出 CSS 選項(xiàng)。Steve Souders’ 的工具 SpriteMe 是另一個(gè)提供 CSS 編碼選項(xiàng)的。SpriteMe 會把現(xiàn)有的網(wǎng)站背景圖片轉(zhuǎn)換成單張 sprite 圖片(我之前提到的“大型” sprite)并提供下載以供編碼入頁面之中。然而這些工具只是有助于創(chuàng)建 sprite,并不能在維護(hù)方面提供多少幫助。Souder 的工具貌似對重新設(shè)計(jì)或布局的網(wǎng)站無效,而且只對那些現(xiàn)有的沒有使用 sprite 方法的網(wǎng)站有用。
可以改進(jìn)現(xiàn)有的工具,而且未來也會有新的工具出現(xiàn)。但是,鑒于以上提到的這些缺點(diǎn),是否還存在這種可能,就是開發(fā)人員依然把精力集中在有限的所得上?
關(guān)注多個(gè)性能提升點(diǎn)
上面提到,HTTP 請求數(shù)是提升網(wǎng)站性能需要考慮的一個(gè)非常重要的因素。但是有別的方法可以減少連接數(shù),包括合并腳本和樣式表,使用遠(yuǎn)程庫文件(即使用 Google 或者 Yahoo!提供的庫文件托管)。
除了 HTTP 請求數(shù)之外還有很多開發(fā)人員可以關(guān)注的用于提升網(wǎng)站性能的因素。包括服務(wù)器啟用 Gzip,正確的放置外鏈腳本,優(yōu)化 CSS 語法,壓縮較大的 JavaScript 文件,提升 Ajax 性能,避免使用已知的會引起性能問題的 JavaScript 語法,等等。

YSlow 顯示了 HTTP 請求數(shù)之外可以提升網(wǎng)站性能的因素
如果開發(fā)人員花點(diǎn)時(shí)間來考慮下所有可以提升網(wǎng)站性能的因素,再權(quán)衡下利弊,也許就有較好的理由可以避免濫用 CSS sprite 了,并且會把精力放在那些物有所值的方面。
總結(jié)
請不要誤解我所說的。許多頂級的 blogger 和開發(fā)人員已經(jīng)稱頌 sprite 的好處很多年了,最近幾年又把這些意見推廣到使用大型 sprite 上來了 – 因此應(yīng)該認(rèn)真得考慮下這些觀點(diǎn)。但是,這種有著完善的體制和系統(tǒng),使得網(wǎng)站維護(hù)任務(wù)簡化并流水化的公司,并不是所有人都能進(jìn)去的。大多數(shù)人都是獨(dú)立工作,或者接受別人創(chuàng)建的項(xiàng)目。這類情況下,大型的 sprite 會導(dǎo)致得不償失的麻煩。
糖伴西紅柿的總結(jié)
標(biāo)題有點(diǎn)醒目 :) 原標(biāo)題的規(guī)矩翻譯為 CSS Sprites:有用的技術(shù)還是潛在的麻煩?
關(guān)于 CSS Sprite,在 Web 標(biāo)準(zhǔn)交流會 第二期的時(shí)候討論過。其實(shí) CSS Sprite 是很有用處的。但是前提是不要超出一個(gè)度的限制?;旧虾芏鄦栴}最終都會歸于如何適度地使用的問題。老話說:過猶不及,其實(shí)還是很有道理的。
對于減少 HTTP 請求數(shù)問題,可以稍作妥協(xié),把圖片分類,盡量把內(nèi)容固定、后期不會有太多變動(dòng)的圖歸入一個(gè) sprite 中,例如一些 icon 。那些會經(jīng)常改動(dòng)的圖片歸入一類,分成幾組 sprite。對于設(shè)計(jì)花哨而生命周期很短的專題來說,真得,花費(fèi)在拼圖上的時(shí)間和經(jīng)歷實(shí)在是有點(diǎn)浪費(fèi)了。
關(guān)于老外的文章,我現(xiàn)在覺得有些絮叨了?;蛟S很多人也會有這個(gè)感覺。其實(shí)應(yīng)該反思下,據(jù)說日本有專門的小冊子來教人做一些非?;A(chǔ)的東西,內(nèi)容步驟細(xì)致到令人發(fā)指得地步?;A(chǔ)的東西大多人會不屑一顧,覺得別人都談?wù)撈婕家伞⒏呒墤?yīng)用了,我還在搞這些基礎(chǔ),多丟人啊。
基礎(chǔ)的東西其實(shí)沒那么簡單的,有誰能真得掌握了這些看上去簡單的基礎(chǔ)呢?看一下這個(gè)基礎(chǔ)問題你真的了解HTML嗎?
曾經(jīng)有一個(gè)高手送我一本書,他寫了 ”Back to basic“ 送我,我在這里送給大家,希望大家都能踏踏實(shí)實(shí)地努力進(jìn)步。
相關(guān)文章
- 網(wǎng)頁制作Webjx文章簡介:在google中搜索一下css sprites這個(gè)名稱,會查出很多信息,并且隨著SEO越來越被人們重視,采用這種技術(shù)來進(jìn)行圖片優(yōu)化的網(wǎng)站越來越多,國內(nèi)幾家大2009-04-02
- 很高興為大家?guī)砹薈SS Sprites 樣式生成工具 3.0版本。 保存的設(shè)置文件也同時(shí)更新了,支持打開舊的文件,會以新的格式保存(舊版本打不開)。 操作界面做了小小的調(diào)整2009-06-23
- 阿里媽媽UED談CSS Sprites技術(shù).2009-10-20
什么是CSS Sprites(圖片合并)技術(shù) 圖文介紹
眾所周知,減少網(wǎng)站加載時(shí)間的最有效的方式之一就是減少網(wǎng)站的HTTP請求數(shù)。實(shí)現(xiàn)這一目標(biāo)的一個(gè)有效的方法就是通過CSS Sprites——將多個(gè)圖片整合到一個(gè)圖片中,然后再用CSS2011-06-21- CSS Sprites技術(shù)不新鮮,早在2005年 CSS Zengarden 的園主 Dave Shea 就在 ALA 發(fā)表對該技術(shù)的 詳細(xì)闡述 。原先只在CSS玩家之間作為一種制作方法流傳,后來出來個(gè) 14 Rules2011-08-02
css sprites技術(shù) CSS Sprites圖片切割術(shù)與圖片優(yōu)化深入理解
近段時(shí)間一直在做前臺的一些東西,涉及到很多div+css的問題,原來這個(gè)叫CSS Sprites技術(shù),我對前臺這些個(gè)東西比較感興趣,所以會去了解多一點(diǎn)2012-12-03- CSS Sprites其實(shí)就是把網(wǎng)頁中一些背景圖片整合到一張圖片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的組合進(jìn)行背景定位2014-12-12
- 這篇文章主要介紹了CSS Sprite從大圖中截取小圖完整教程的相關(guān)資料,需要的朋友可以參考下2014-12-29



