Web字體圖標-自動化方案

原文連接jiangxiaokun.com/web/2019/01…css

緣起

Web從誕生之日起是爲了展現圖片文字的,最典型的表明就是imgspan。這是構建豐富的Web頁面的基石,也是理解瀏覽器表現(Browser performance)的基礎。本文將從從圖片中的小圖標切入,介紹一下Web小圖標的技術方案的演進。html

Web中小圖標方案的演進

筆者原本打算從Image Sprites,到 Svg Spritesiconfontsvg Icon 總體介紹一遍的,在查閱資料以後發現已經有大佬寫過了:Web中的圖標-大漠,介紹得算是很詳細(絕大部分應用場景都已經能覆蓋了),這一部分本文就再也不贅述了。前端

筆者的補充

  1. MDN關於 Image sprites備註:當使用 HTTP/2 時,使用多個小流量請求實際上可能更爲帶寬友好。
  2. DataURI(圖片Base64)(筆者的建議是慎用,它可能成爲一個性能瓶頸),由於CSS在解析過程遇到Base64,每次都須要解碼,這會阻塞關鍵CSS的渲染,具體能夠看這一篇文章:深挖 data URI 性能瓶頸

趁機糾正了本身以前的錯誤:Gzip是針對html/css/js的,.wotf/.png/.ico 等圖片資源是不進行Gzip壓縮,若是不肯定能夠查看Network中的Response Headersvue

言歸正傳

接下來終於輪到了本文中的主角: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 生成的字體所有無法用了。終於忍無可忍……前端工程化

探索方案

由於源項目中使用gulpwebpack打包,心中最理想的方案固然是webpackplugin或者loader,或者gulpplugin。嘗試過gulp-iconfont結合gulp-iconfont-css已經等等其餘方案,要不是由於一些細節方面沒有配置成功,要不就是成功構建出來的字體圖片有明顯的偏移或者鋸齒。多番查閱資料和實踐以後終於發現了一個不那麼起眼的庫webfonts-loader

筆者曾經嘗試過的:gulp-iconfontgulp-iconfont-csswebfontloader ……and so on.

webfonts-loader

第一眼見到TA的時候,我不曾想過這將會是陪伴我許久的那一個,不管是從TA可憐的78❤️,仍是做者本人jeerbl的知名度,但做爲一個勇(zou)於(tou)嘗(wu)鮮(lu)的前端,仍是認真地讀了一下TAREADME,看到了熟悉的webpackloader配置和js的語法,決定好好地實踐一下。(扯遠了)

原理(工做流程)

webfonts-loader(藉助webpack)如何一步一步地將svg的圖標處理成咱們最終想要的樣子?

How does the webfonts-loader which work with webpack build svg icons step by step ?

先來看最關鍵的3份配置:

scionfont.js
module.exports = {
	files: [
		'./svg/*.svg',
	],
	fontName: 'bicon',
	classPrefix: 'bicon-',
	fixedWidth: true,
	types: ['eot', 'woff', 'ttf', 'svg'],
	cssTemplate: './template.hbs'
};
複製代碼
iconfont.js loader
{
    test: /siconfont.js/,
    use: [
        'vue-style-loader',
        'css-loader',
        {
            loader: 'webfonts-loader',
            options: isProd ? {
                fileName: assetsPath('img/[fontname]-[hash:7].[ext]')
            } : {}
        }
    ]
}
複製代碼
fonts loader
{
    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        limit: 10000,
        name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
    }
}
複製代碼
  1. 首先,webpack解析到 import './assets/fonts/siconfont.js'
  2. 接着,webpack會將對應的siconfont.js加載到webpack的工做流中
  3. siconfont.js經過正則匹配到了對應的siconfont.js的webpack相應的 loader(上面第2份配置)
  4. 首先使用webfonts-loader來處理這個xx.jswebfonts-loader解析這個siconfont.js(上面的第一份配置) 以後, 會將當前目錄svg下的全部svg圖標文件都加載進來,而且將相應的CSS模板也加載了進來,而且經過一些項的配置

e.g:配置 types: ['eot', 'woff', 'ttf', 'svg'],表示會打包出四種字體圖標文件

  1. 接下來的步驟就簡單了:webfonts-loader處理完成以後輸出兩種文件流:(1).eot/.woff 等字體文件流 (2) 對應的關聯css流
  2. 文件流下一步進入css-loader,該importimport,字體圖標路徑該resolveresolve,還有其餘可能須要的工做。
  3. 最終生成的CSS可能經過style-loader直接內嵌到html 的style標籤中,也能夠經過Extract插件提取出來整合到最終頁面的CSS 中,而後經過link使用

再一次感覺到 webpack 自動收集依賴和管理依賴,真的是很強大,爲咱們省了太多心

大功告成

藉助着webpack的熱更新機制,咱們能夠很方面地去更新svg文件夾下的字體文件,並即時使用。使用步驟:

  1. 拖入文件 left-arrow.svg
  2. 在組件中對應DOM上添加類名(class): bicon-left-arrow
  3. 刷新瀏覽器,字體圖標已經加上~

寫在最後

文中的方案已經在手機搜狐網手搜體育頻道等多個項目中實踐和使用,能覆蓋絕大多數業務場景。文中完整的示例能夠查看 vue-ssr-start ,歡迎 star※

Vue-ssr-start 是我學習從零開始搭建一個SSR腳手架的理解和記錄,還有一些對前端工程化的思考和探索,會持續迭代並加上完整的註釋,歡迎watch。水平有限,出錯不免,歡迎各位同窗多多指正,共同進步~

參考

webfonts-loader

Web中的圖標-大漠

深挖 data URI 性能瓶頸

icomoon

相關文章
相關標籤/搜索