前端Vue字体优化三部曲(webFont、font-spider、spa-font-spider-webpack-plugin)
引言
最近前端引入了UI给的思源黑体字体文件,但是字体文件过于庞大,会降低页面首次加载的速度,目前我的项目中需要用到如下三个字体文件,加在一起24M左右
一、webFont
首先想到的是我们可以通过webFont技术对自己进行压缩,然后利用css@font-face方法对压缩后的字体文件进行引用操作,我相信这也是大多数开发者的项目用的最多的一个技术了吧?将字体文件压缩成woff2格式,基本相当于原字体文件ttf的0.3-0.5大小,目前已知的比较好用的网站如下:
字体文件压缩网站:https://transfonter.org/,可将ttf字体文件转换为base64格式,然后我们在index.html文件中引用该css文件即可
如上图,我们选择woff2文件类型,也是目前最常用压缩率最高的字体文件类型了
压缩完成,我们点击Download看看下载的文件都是什么:
解压文件我们发现得到的字体包是不是比原来小了一半,而且带有demo文件和转化好的css文件,不得不说这个网站真贴心
如下图展示,这是我们设计图目前用到的思源黑体的三种字体,有没有一种感觉,用webFont技术字体文件还是过于庞大(如下图:14M),当我们打开首页,尤其项目中首页文字较多时,还是会出现页面先加载默认字体,然后等字体文件下载完成时,又变为了设计的字体这个问题,这对于对用户体验有较高要求的项目来说,此问题无疑是很严重的。虽然目前我做的这个项目是PC端的系统,但为了以防万一,再加上对技术的一点点追求,决定还是要找一找更好的解决方案…
二、font-spider
由于此前对前端字体优化有一些经验,让我想到字蛛这个技术,既然领导把字体的任务交给我,就是对咱的信任,如果能把字体文件缩小这个事情有一个质变,那岂不是让人很有成就感的一件事情?
具体方案如下:
- 全局安装font-spider
npm install font-spider -g
- 将我们项目中所用到的字都总结到如下图的index.html中,或者test.html,名称不重要,不一定是我们的系统中默认的index.html文件
- 在项目根目录下创建一个 fonts 文件夹,并放入你的字体文件。
在 index.css 中定义 @font-face:
@font-face {
font-family: 'Lato-Medium';
src: url('./fonts/SourceHanSansCN-Regular.ttf');
src: url('./fonts/SourceHanSansCN-Regular.woff') format('woff');
}
index.html
这里首先在<head>处要引入index.css文件<link rel="stylesheet" href="index.css">,然后在<body>处压缩我们想要的字体吧,这里只能压缩静态字体哦
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1.0,minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>font spider</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div>
<!-- 这里对应的是Regular的压缩包 -->
<div class="bold">
abcdefghijklmnopqrstuvwxyz
</div>
<!-- 这里对应的是Medium的压缩包 -->
<div class="medium">
ABCDEFGHIJKLMNOPQRSTUVWXYZ
</div>
<!-- 这写在class元素之外的就没有对应的压缩包了 -->
123456
</div>
</body>
</html>
- 输入font-spider [options] <url|localfile>运行工具。
font-spider ./path/to/your/test.html
这种办法,得到的字体文件肯定会被优化到极致,但是不足的是它只能将index.html中的字识别成新的字体,不能动态的渲染其他页面中的字,因此后来又有了新的方案
三、终极方案:spa-font-spider-webpack-plugin
这是github上的一个webpack插件,
https://github.com/zhuzhengshou/spa-font-spider-webpack-plugin
直接在启动或打包的时候提取所需文字,不用单独再将页面的文字复制到index.html里。
npm i spa-font-spider-webpack-plugin
"spa-font-spider-webpack-plugin": "^1.1.1",
如下为vue-cli5.0版本的写法,其他版本请自己转换为该版本的webpack配置写法
const {defineConfig} = require('@vue/cli-service')
const SPAFontSpiderWebpackPlugin = require("spa-font-spider-webpack-plugin")
module.exports = defineConfig({
lintOnSave: false,
transpileDependencies: true,
devServer: {
...
},
configureWebpack: {
...
},
chainWebpack: config => {
config
.plugin('spa-font-spider')
.use(SPAFontSpiderWebpackPlugin, [{
fontFamilyPkgList: [
{
url: 'http://localhost:3002/font/SourceHanSansCN-Regular.ttf',
name: 'Source Han Sans CN'
},
{
url: 'http://localhost:3002/font/SourceHanSansCN-Medium.ttf',
name: 'Source Han Sans CN-Medium'
},
{
url: 'http://localhost:3002/font/SourceHanSansCN-Bold.ttf',
name: 'Source Han Sans CN-Bold'
}
],
preload: true,
complete: true,
silent: true
}])
.end()
}
})
在这里我们可以清晰的看到,该插件已经将打包过的js文件一一识别出来,肯定做了文字识别处理
在控制台我们可以看到提取的文字,但是我觉得这里有个问题就是提取的并不止这100多个,这应该是插件的bug,因为我们在系统中所用到的字并不止这100多个,但都显示成功了,目前还没有做过多的研究为什么在控制台只报出了这100多个,它很有可能没有计算出*中的个数!
自此,整个字体文件被缩减到了200k,页面加载效率提升了很多,在移动端效果会更明显,而这应该是一个让开发者很满意的一个结果了。
此文原创,转载请注明出处