需求导向
作为一个前端,肯定遇到过这个需求,UI做出来的设计稿利用了特殊字体。虽然对于前端来说,管你什么字体,我微软雅黑通吃,但是有时候UI会很执着,“这个一定要实现,你直接切一张图片上去也行”。为了省事,我们肯定是直接切一张图上去啊,但是每次切完图之后,图片都需要加工优化。每次替换文字都要重新编辑psd图 -> 切图 -> 优化图片。所以还原高保真的时候要遵循一个原则,能用html实现的就不要用图片代替,美言之为了性能,其实还是为了无止境的需求变更。
我们知道使用特殊字体,只要引入字体的ttf文件(ttf文件,这里不做介绍,可自行百度)就行。如下:
@font-face {
font-family: "fashion";
src: url('./fashion.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
.fashion-font {
font-family: "fashion";
}
但是字体文件一般包含所有字体,字体文件大小几M,对于前端来说,肯定是不能接受的,所以我们需要对ttf文件进行打包操作,只引用用到的文字,这里我们称静态文字,后面会介绍动态文字的解决方案。
font-spider
font-spider是一个npm库,可以解析html用到特殊字体的文字,按需打包,替换原来的ttf文件,并且在ttf文件目录下生成一个.font-spider文件夹存放原来总的ttf文件。使用下面命令可进行打包操作:
sudo font-spider --debug src/**/index.html
--debug命令可以查看解析过程。
结合webpack
如果你是传统的多页面应用,这样的打包方式是没问题。但是现代前端工程化之后,前端只会有一个index.html入口文件,且css文件是通过js引入的,font-spider无法解析js里的css文件,所以那些引用font-family: "fashion";字体的文字都会失效。这里提供两个解决方案:
1.在html里引入绝对路径的css文件,https://www.baidu.com/index.css。
2.采用相对路径,基于网站根目录。一般情况下webpack工程下都会在项目根目录下建一个static目录存放静态文件。路径如下:
<link rel="stylesheet" href="./static/mgday2018/font/font.css" type="text/css">
这里有一点需要注意,打包的时候,font-spider是根据index.html检索css所对应的相对目录,比如项目中有多个html文件,所以他们所对应的字体文件的位置需要根据html所在的位置。而且你使用字体的方式,不是在使用的地方上加font-family: "fashion";样式,而是通过class的方式引入(如class="fashion-font"),这样打包的时候才能被依赖。
<link rel="stylesheet" href="./static/mgday2018/font/font.css" type="text/css">
<!-- 下面的地址是为了兼容font-spider的打包地址 -->
<link rel="stylesheet" href="../../../static/mgday2018/font/font.css" type="text/css">
最终实现效果

动态文字
有些人会说你这是静态文字啊,有些文字是通过后端接口返回的,我们无法提前打包啊。这里提供三个解决方案:
1.利用fontmin.js
fontmin.js允许你提前将需要的问题,提前打包,即使文字不在html里。但这其实这只是解决文字不在html里,还是没解决后端接口返回的文字的问题。参考链接: 移动端引入的字体文件过大处理方法。
2.实时打包
原理:搭建一个node中间层,每次接口返回的时候,先调用node服务fontmin,打包接口中用到的文字,然后返回一个静态地址给前端,前端拿到接口数据和一个静态css地址,先加载css地址,再加载文字。但是这会造成很大的资源浪费,且每次生成一个字体文件。这里再提供一种思路,node中间层每次获取接口文字,重新编译页面中所有需要用到的文字(这里会有缓存对比,如果文字都已经包含,则不重新打包),再把css地址和数据返回给前端。但无论如何,只能针对几个接口开放实时打包,否则再大的服务器也抗不住这种压力。
3.引入整个字体文件
回到老问题,引入整个字体文件。首屏所需要用到的字体文件先单独打包,先加载首屏需要用的字体文件,再通过延迟加载和cdn,加载整个字体文件。这样能比较好的实现动态文字的问题。
总结
可见很明显,动态的文字其实不适合特殊字体,无论怎么优化,都会浪费很多资源,性能也是一个问题。所以我们只能期望将来某一天,网速飞快了,几M的文件能瞬间加载了,这个问题就迎刃而解了。
写作时间:20181118