現代網站設計中充滿了各式各樣的 icon,若是自有品牌或產品,設計師更常會為了強化視覺一致性而客製一整套的 icon 圖示。
而從我們工程師的角度來看,icon 本質上就是一種圖片,既然是圖片的一種形式,當 icon 使用量一多,自然就會牽涉到與圖片相同的效能問題。為什麼 icon 太多會影響效能?
為什麼 icon 太多會影響效能?
通常 icon 是以圖片檔案(例如: SVG 或 PNG )呈現,若網站載入時每個 icon 圖示都會觸發一個 HTTP Request,不僅延長載入時間,一次大量圖片載入會增加 Render 渲染時間或主執行緒負擔。
別忘了,Client Browser 的 JavaScript 執行是單執行緒,無論是同步或非同步操作,本質上都還是在爭奪主執行緒資源。如果沒有另外開啟 Web Worker,圖片的下載、解析與渲染過程都會壓在主執行緒上,拖慢頁面的渲染。
理論上面對大量圖片的載入,我們會使用 Lazy Load 的方式,當網站可視範圍出現圖片才動態載入該張圖片。但是 icon 這種圖示,如果 Lazy Load 在畫面動態載入渲染:讓使用者看到那載入與渲染的過度期是很奇怪的事情。
所以面對這種狀況,我們會將 icon 轉成字體 Font 的形式,不要讓 icon 獨立發出圖片的請求,也就是 Icon Font。
Icon Font 是什麼?
Icon Font 就像是一組「專為圖示設計的字型」。我們可以把自己挑選或設計好的 SVG 圖示匯入工具(例如 IcoMoon),產出一個字型檔,並搭配 CSS 偽元素使用,例如購物車 icon 在樣式黨就會像這樣:
.icon-cart::before {
content: "\e900";
font-family: 'MyIconFont';
}
而 HTML 則是
<span class="icon-cart"/>
這種做法讓所有圖示只需要載入一次字型檔即可,後續 icon 顯示都是透過 CSS 偽元素去顯示對應 icon ,這樣可以大幅減少請求數量與檔案大小。
適合使用 Icon Font 的情境
如果這些 icon 是 「單色」且重複使用率高,那可以交給 Icon Font 處理,效能與維護性都會更好一點。
使用 Icon Font 優勢
效能提升:減少額外的圖片資源請求
理論上只需字型檔與樣式設定,就能載入所有圖示,可以減少原本 icon 靜態圖片資源的 request 數量。
不論何種裝置都能保持清晰度
從圖片檔案變成 Font 字體,在 Apple Retina 螢幕或各種裝置解析度,都能保持清楚銳利的效果,設計師也不用在那邊什麼 1x、2x、3x 出圖片的倍數、複數大小檔案。
開發相對友善
因為 Icon Font 就是字體,所以只需操作 CSS class 就能改寫樣式顏色和大小,修改很方便。
雪碧圖不好嗎?
雪碧圖(Sprite Image)是將多張小圖統整到一張大圖上,然後透過定位去顯示這張大圖上的特定小圖片。其作法是:將多張小圖整合成一張大圖,再透過 CSS 的背景定位(background-position
)來顯示對應的小圖。這種方式同樣能減少圖片請求次數,對效能提升也有幫助。
在前文提到,Icon Font 適合用在「單色、重複使用」的情境。但如果 icon 是多色、有陰影或漸層等複雜效果,就不適合使用 Icon Font。這時候,雪碧圖會是更實際的選擇。
項目 | Icon Font | Sprite Image 雪碧圖 |
---|---|---|
適合圖示類型 | 單色、簡單圖示 | 多色、設計較複雜 |
縮放 | 本質上就是字體,font-size 怎麼設定也能保持清晰 |
按照雪碧圖不同的設定,有的放大會糊掉 |
CSS 變色能力 | 透過 CSS color 改字體顏色,即能改變 icon font 顏色 |
沒辦法 |
動畫控制 | 可用 CSS 動畫 | 因為是在大圖上定位,所以實作動畫限制較多 |
載入資源大小 | 較小 | 按照合併放在上面的 icon 數量而定,塞越多圖片那這張雪碧圖當然會越大 |
IcoMoon
以筆者而言,我們公司有使用 IcoMoon,它是一個專門用來產生 Icon Font 的線上網站工具,支援使用者匯入自訂 SVG 圖示(這裡指的是 UI 設計師畫的 icon),並快速轉換成字型檔.woff
, .ttf
等與 CSS。以便在網頁中以最少請求數載入 icon。
相關網站的線上操作流程我就不上來了,可以參考以下幾篇文章介紹:



