首页/文章/前端

🪒Web端字体切割压缩方案

2024-09-04
11654 分钟
...

今天接到一个系统需求,需要将系统内的文字替换为鸿蒙OS的字体(developer.huawei.com/consumer/cn…),但是鸿蒙OS的字体单Regular的文件就有8M+。这个直接放到网页上,会极大影响使用体验。

于是乎,开始考虑怎么开始对字体文件进行压缩。

第一种方案

一般来说,字体格式体积由大到小排列(性能从差到好):

ttf,eot(IE8),woff,woff2

从官网下载的鸿蒙字体是ttf格式的,尝试用了woff2格式的(github.com/IKKI2000/ha…),但是还是有4M多。对于Web端来说,还是太大了。

第二种方案

把系统内未使用过的汉字裁掉,只保留系统内使用的汉字,这样就可以大大减少字体文件体积。但是呢这种方式只适用于固定内容的网页,像一些动态内容(服务端返回的汉字,评论等)就没法适应。

这种方式可以使用 Font-spider-Plus 组件进行压缩。具体方法可以看到组件文档。

第三种方案

上面两种方式,对于我来说都不太理想,于是只能继续寻找方案。很好奇,鸿蒙的官网也是用的鸿蒙的字体,那它是怎么兼顾性能的呢?

通过Devtool能看到,官网加载的字体文件非常多,但是每个只有几十kb。像是被切割成了N份。

于是翻看对应的css文件,发现了这一句注释

/** generated by https://github.com/voderl/font-slice */

进入github仓库一看,发现了今天的主角 font-slice。(组件Demo地址

效果

得意黑字体为例为例:

处理前 ttf 大小 2074KB,woff2 大小 928KB.

处理后每个类型的字体生成 95 个文件:

ttf 总大小为 2.3M (最小文件 3.4K,最大文件 55K)

woff2 总大小为 1.3M (最小文件 1.5K,最大文件 33K)

实际加载页面的体积由页面使用的字符决定,以该页面为例,只需要加载 386KB 就能覆盖全部字符。

原理

将中文字体按照 Google Fonts 的切割子集方案,生成多个较小体积的资源包。仅需加载小部分字体资源即可展示完整页面。

即它采用了机器学习等手段,将字体拆分成合适的粒度,比如把一个 4MB 的字体包分成 100 个 40KB 的字体包,这样的话,一般网页中使用到的中文也只是一部分字体,只需要加载多个资源包就能完全覆盖。同时,就算网页中有很多生僻字,需要付出的代价也只是多加载几个资源包。

使用

1. 安装

npm install --save-dev font-slice

2.创建脚本

const path = require("path");
const createFontSlice = require('font-slice');

createFontSlice({
  // fontPath
  fontPath: path.resolve(__dirname, 'YourPath.ttf'),
  // outputDir
  outputDir: path.resolve(__dirname, './output'),
  fontFamily: 'HarmonyOS_SansSC',
  // 是否需要在生成完成后打开预览页面,默认为 true,如果为 false 不会生成 index.html 及启动服务器
  preview: false,
})

这一步所有的配置项可以查看:github.com/voderl/font…

3. 配置script

我是把这个脚本配置到了package.json的scripts里面,后续就可以通过npm run来运行了。这一步可自行决定。

4.引入CSS

运行完成后,会输出font.css和切割成多份的字体文件。将css引入页面。页面内的地方就可以正常使用font-family了。

缺点

这种方式有个缺点,就是如果新出现的文字没有加载对应的分片,会有一瞬间的文字闪动。因为需要加载新的文字分片。

参考文档

  1. web性能-字体优化-掘金
  2. font-slice组件
  3. 字蛛+(Font-spider-plus)
  4. 鸿蒙字体下载

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
前端2026-07-17
HTML Form 可以把 POST 响应加载进 iframe
在接入支付验证、身份认证或第三方授权页面时,我们经常会遇到这样的流程: 1. 后端返回一个第三方接口地址。 2. 这个地址必须通过 请求访问。 3. 接口返回 HTML,或者重定向到真正的验证页面。 4. 验证页面需要嵌入当前网站,而不是打开新标签页。 5. 验证完成后,当前页面继续执行后续业务。 第一次遇到这个需求,很容易想到: 但涉及第三方支付时,这种方式通常会遇到 CORS、Cookie、重定向和跨域页面读取限制。 实际上,HTM...
学习
前端2026-05-29
前端判断一个网页是否允许被 iframe 内嵌
前端 不能 100% 准确提前判断 一个网页是否允许被 iframe 内嵌,因为决定权主要在目标网站返回的 HTTP 响应头 里,而普通前端 JS 通常读不到跨域页面的响应头。 核心判断看这两个东西: 1. 老一点但仍常见。 表示完全不允许被 iframe 嵌入。 表示只允许同源页面 iframe 嵌入。 以前有这个,但现代浏览器支持很差,基本不建议依赖。 2. 现在更推荐看这个。 表示不允许任何页面嵌入。 表示只允许同源嵌入。 表示只...
学习
前端2026-03-20
网页唤起 Android App 调试笔记(App Links)
  在最近的项目中,我遇到了 网页访问特定 URL 应该唤起 Android App,但实际只打开网页 的问题。通过调试和排查,整理出以下经验和步骤。 1\. 项目与环境信息(脱敏处理) 网站域名: 唤起页面: Android App 包名: intent filter 配置示例: assetlinks.json 已上线,包含 App 的 SHA256 签名指纹 2\. 问题现象 用户访问 页面时, 网页打开了,但 App 没...
学习
前端2026-03-02
深入理解 Cookie:安全属性、访问边界与渲染场景实践
本文系统梳理 Cookie 核心机制,聚焦 HttpOnly/SameSite 等安全属性 、 访问权限边界 、 CSR/SSR 差异 ,附关键代码示例与安全清单。适合开发查阅与知识沉淀。 一、Cookie 是什么?为什么需要它? HTTP 是无状态协议。Cookie 是服务端通过 响应头下发、浏览器自动存储并在后续 同源请求中携带 的小型文本数据(通常 ≤4KB),用于: 会话维持(Session ID) 用户偏好(语言/主题) 跨请...
学习
前端2026-03-02
退出登录时 Cookie 清除指南
核心结论 :登出 ≠ 单方面操作。HttpOnly 与非 HttpOnly Cookie 需 前后端协同清除 ,缺一不可。残留 Cookie = 安全隐患 + 用户体验漏洞。 🔒 为什么不能“一键清空”? 浏览器出于安全设计: 后端 :只能通过 响应头清除 自己设置过 的 Cookie(需属性完全匹配) 前端 JS :可读写非 HttpOnly Cookie,但 无法触碰 HttpOnly Cookie 无“清除全部”API :任何服...
学习
前端2025-12-15
懒加载图片在同一个 Item 中逐个出现的原因与解决方案
懒加载图片在同一个 Item 中逐个出现的原因与解决方案 适用场景 :使用原生 实现图片懒加载的动态列表,每个列表项(item)包含多张图片。 📌 问题描述 在开发一个动态渲染的列表时,每个 item 中包含三张图片,并使用 HTML 原生的懒加载属性: 观察到的现象: 开启懒加载时 :三张图片 不是同时出现 ,而是 从左到右(或从上到下)依次加载显示 ,有明显的时间差。 关闭懒加载(移除 )后 :三张图片 看起来是一起出现的 ,视觉...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录