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

相关文章
相关标签/搜索