原文連接:jiangxiaokun.com/web/2019/01…css
Web
從誕生之日起是爲了展現圖片
和文字
的,最典型的表明就是img
和span
。這是構建豐富的Web頁面的基石,也是理解瀏覽器表現(Browser performance
)的基礎。本文將從從圖片
中的小圖標
切入,介紹一下Web
中小圖標
的技術方案的演進。html
筆者原本打算從Image Sprites
,到 Svg Sprites
到iconfont
到 svg Icon
總體介紹一遍的,在查閱資料以後發現已經有大佬寫過了:Web中的圖標-大漠,介紹得算是很詳細(絕大部分應用場景都已經能覆蓋了),這一部分本文就再也不贅述了。前端
Image sprites
的備註
:當使用 HTTP/2 時,使用多個小流量請求實際上可能更爲帶寬友好。DataURI
(圖片Base64
)(筆者的建議是慎用
,它可能成爲一個性能瓶頸),由於CSS
在解析過程遇到Base64
,每次都須要解碼,這會阻塞關鍵CSS的渲染
,具體能夠看這一篇文章:深挖 data URI 性能瓶頸趁機糾正了本身以前的錯誤:
Gzip
是針對html/css/js
的,.wotf/.png/.ico
等圖片資源是不進行Gzip
壓縮,若是不肯定能夠查看Network中的Response Headers
vue
接下來終於輪到了本文中的主角:Icon Font 登場了~~~。相比位圖 png Sprites
而言,使用字體圖標能夠不受限於屏幕分辨率
,並且字體圖標另外一個優點是:只要適合字體相關的CSS屬性
都適合字體圖標。筆者通過調研以後在項目中肯定了 Icon font
的方案。webpack
最開始是將svg
上傳到 https://icomoon.io/
,生成對應的字體和樣式文件,而後引入到項目中。git
問題1:每次
update
圖標都須要重複上面的步驟,而後再把文件下載下來,而後複製到項目源碼中替換舊的文件github
問題2:樣式文件很差管理,由於
icomoon
下載下來的樣式文件由於兼容性的須要,是須要進行修改的,以至於每次得摘出icon-list
, 原有已進行兼容的代碼保留。web
問題3:當時
icomoon
免費版 沒有提供去色構建字體圖標的功能,致使還須要對生成的樣式進行必定的定製(調色,調位置)gulp
問題4:更換了設計師以後,設計出來的
某些圖標文件
引入以後,icomoon
生成的字體所有無法用了。終於忍無可忍……前端工程化
由於源項目中使用gulp
和webpack
打包,心中最理想的方案固然是webpack
的plugin
或者loader
,或者gulp
的plugin
。嘗試過gulp-iconfont
結合gulp-iconfont-css
已經等等其餘方案,要不是由於一些細節方面沒有配置成功,要不就是成功構建出來的字體圖片有明顯的偏移或者鋸齒。多番查閱資料和實踐以後終於發現了一個不那麼起眼的庫webfonts-loader
筆者曾經嘗試過的:gulp-iconfont、gulp-iconfont-css、webfontloader ……and so on.
第一眼見到TA的時候,我不曾想過這將會是陪伴我許久的那一個,不管是從TA可憐的78❤️
,仍是做者本人jeerbl
的知名度,但做爲一個勇(zou
)於(tou
)嘗(wu
)鮮(lu
)的前端,仍是認真地讀了一下TA
的README
,看到了熟悉的webpack
的loader
配置和js
的語法,決定好好地實踐一下。(扯遠了)
webfonts-loader
(藉助webpack
)如何一步一步地將svg的圖標處理成咱們最終想要的樣子?
How does the webfonts-loader which work with webpack build svg icons step by step ?
先來看最關鍵的3份配置:
module.exports = {
files: [
'./svg/*.svg',
],
fontName: 'bicon',
classPrefix: 'bicon-',
fixedWidth: true,
types: ['eot', 'woff', 'ttf', 'svg'],
cssTemplate: './template.hbs'
};
複製代碼
{
test: /siconfont.js/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'webfonts-loader',
options: isProd ? {
fileName: assetsPath('img/[fontname]-[hash:7].[ext]')
} : {}
}
]
}
複製代碼
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
複製代碼
import './assets/fonts/siconfont.js'
,siconfont.js
加載到webpack的工做流中siconfont.js
經過正則匹配到了對應的siconfont.js
的webpack相應的 loader(上面第2份配置
)webfonts-loader
來處理這個xx.js
,webfonts-loader
解析這個siconfont.js
(上面的第一份配置
) 以後, 會將當前目錄svg
下的全部svg
圖標文件都加載進來,而且將相應的CSS模板也加載了進來,而且經過一些項的配置e.g:配置
types: ['eot', 'woff', 'ttf', 'svg']
,表示會打包出四種字體圖標文件
webfonts-loader
處理完成以後輸出兩種文件流:(1).eot/.woff
等字體文件流 (2) 對應的關聯css流
css-loader
,該import
的import
,字體圖標路徑該resolve
的resolve
,還有其餘可能須要的工做。CSS
可能經過style-loader
直接內嵌到html 的style
標籤中,也能夠經過Extract插件
提取出來整合到最終頁面的CSS 中,而後經過link
使用再一次感覺到
webpack
自動收集依賴和管理依賴,真的是很強大,爲咱們省了太多心
藉助着webpack
的熱更新機制,咱們能夠很方面地去更新svg文件夾
下的字體文件,並即時使用。使用步驟:
left-arrow.svg
class
): bicon-left-arrow
文中的方案已經在手機搜狐網和手搜體育頻道等多個項目中實踐和使用,能覆蓋絕大多數業務場景。文中完整的示例能夠查看 vue-ssr-start ,歡迎 star※
Vue-ssr-start 是我學習從零開始搭建一個
SSR
腳手架的理解和記錄,還有一些對前端工程化的思考和探索,會持續迭代並加上完整的註釋,歡迎watch
。水平有限,出錯不免,歡迎各位同窗多多指正,共同進步~