网页应用中文字体

疫情真可怕,公司要从游戏平台转成在线自营游戏了,我便担起了游戏开发工程师。

在游戏开发过程中,发现设计对字体要求很高,系统自带的字体已经不能满足要求了,所以必须在网页上使用中文字体。

单个中文字体动辄10M以上,而且设计需要使用到五六种字体,用户肯定带宽肯定吃不消,这时候就需要按需裁剪字体文件。

FontSpider 字蛛
FontSpider 字蛛

FontSpider是一个通过分析本地 CSS 与 HTML 文件获取 WebFont 中没有使用的字符,并将这些字符数据从字体中删除以实现压缩,同时生成跨浏览器使用的格式的工具,非常简单好用。

FontSpider基础用法

安装

sudo npm install font-spider -g

样例

<html>
    <head>
        <style>
            /*声明 WebFont*/
            @font-face {
            font-family: 'pinghei';
            src: url('../font/pinghei.eot');
            src:
                url('../font/pinghei.eot?#font-spider') format('embedded-opentype'),
                url('../font/pinghei.woff') format('woff'),
                url('../font/pinghei.ttf') format('truetype'),
                url('../font/pinghei.svg') format('svg');
            font-weight: normal;
            font-style: normal;
            }
        </style>
    </head>
    <body>
        <p style="font-family: 'pinghei'">
            使用选择器指定字体
        </p>
    </body>
</html>

进行字体裁剪

font-spider index.html

进阶用法

由于游戏会有大量的文本会从后端服务器返回,纯前端页面可能会有不少字符是没有的,所以需要将后端的中文全部整理出来才行。

# 从源代码中找出全部含中文的代码
grep -P '[\p{Han}]'  -r ../../src  > tmp.html
# 过滤掉无用的符号和英文
node process.js
# 开始合成index.html
cat 1.html > index.html
cat tmp.html >> index.html
cat 2.html >> index.html

# 裁剪字体
font-spider ./index.html

# 复制新字体文件到项目中
cp *.ttf ../../src/assets/font/

#清理
rm -f ./tmp.html

process.js代码

var fs = require('fs')

var content = fs.readFileSync('./tmp.html', 'utf-8')

//只保留中文
var reg = /[\u4e00-\u9fa5]/g;
var words = content.match(reg)
var result = words.join("")

fs.writeFileSync('./tmp.html', result, 'utf-8')

经过裁剪完,字体体积从原来的36M降到320KB,真爽!

测试过程发现,字体文件加载速度总是偏慢,有时候文字出来后,才会被渲染成新的字体。查看了Network后发现,字体文件请求可能晚于文字的出现,所以需要改一下webpack的url-loader工具,将字体文件以base64的方式打包进入main.js

{
    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        limit: 900000, //把字体文件大小限制提高到900kb,尽可将小字体统统打包进去JS
        name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
    }
}