1
头图

中文网字计划是收录众多中文字体并通过 Web Font 的形式为 网站开发者 提供美丽字体的项目。

中文网字计划致力于在互联网中提供更加便捷实用的全字符集中文渲染方案。中文网字计划通过精巧设计的字体分包方式,将庞大的字体文件切割为多个小型静态分包部署于云端,在全网领域内都可快捷、稳定地进行加载。为提高中文字体在网络中的流通体验而努力!

为什么要使用独特的中文字体

  • 提高艺术风格的表现力

前端领域是信息呈现最为丰富、风格最为灵活的一个技术领域。它不仅包括了各种以文本为主的新闻、博客、论坛网站,还涵盖了各类生动灵活的数据可视化网站,以及风格别致的网页小游戏。在许多注重表现细节网站中,中文字体的作用不容小觑。例如在像素游戏使用像素字体来符合整个游戏世界观,数据可视化网站中运用特殊装饰字体来呈现主题所表达的情感,在个人博客中也有运用飘逸轻盈的字体来展现个人的艺术追求的例子。可以说,选择适合的字体是使得网页呈现独特风格的关键要素之一。

  • 提高产品的风格辨识度和国际统一度

中文字体能够有效地呈现品牌形象,提高产品的辨识度,帮助产品更好地传递自己的理念和价值观。中文字体在不同的设计元素中也有着其独特的应用。

举例来说,米哈游开发的原神中采用 汉仪文黑字体,它在中、日、韩、英四种语言环境下表现出一致的艺术风格和文字表现力。即使在同一图片中呈现也没有违和感,这对于不同语言玩家在游戏中的视觉效果和用户体验来说具有非常强烈的提升。

在当前的互联网环境中,英文字体的应用已经非常普遍。由于英文字符数量较少,因此加载整个字体包并不会对网页造成影响。然而,中文字符与英文字符相比,其数量和轮廓复杂度都更高。因此中文字体体积较英文字体大非常多,而且加载中文字体往往会占用大量的网络带宽。对于原生应用程序来说,可以通过内置字体包等方式解决这个问题,但这个弱点对于 Web 网页加载则是致命的。

如何实现 Web 场景下的网络字体加速

手动、自动切割字体文件

目前一种在网页中使用中文字体的方法是分析网页所包含的中文字符,将字体切割出来,单独分包存储在服务器中。这种切割方式可以极大地减小字体大小对带宽的影响,适用于个人博客等类型的网站。然而,随着一个项目越来越大,所需要进行的切割文本越来越多,采用这种非全量级的加载方式,可能会导致不同的文章涉及的文字不同,从而造成打包字符区间不同,影响服务器的缓存和资源利用率。常见的工具有:字蛛、fontmin、fonttools 等

缺点:需要手动执行、只适用于静态场景、影响缓存效率

Google fonts 方案

在 Google Fonts 网站中,Google 采用最新的 CSS 特性 unicode-range 来实现按需加载 CJK (中日韩) 字体,并成功地实现了中文字体在网页端的全量级按需加载。同时提供了如站酷系列、Noto 系列等字体的效果展示。从技术上看,所有加载文件为静态文件,可以通过 CDN 一次发布,随处加载,且具有可靠的速度和稳定性。即使如博客论坛等专注长文本类型的网站,也可使用。但受限于版权问题,Google Fonts 中仅有开源字体,如果需要特殊字体需要进行自托管

https://fonts.googleapis.com/css2?family=Lexend+Exa:wght@900&family=Roboto:wght@100&display=swap

缺点:分包较大、国内访问不佳或需要代理、需要自托管

中文网字计划方案

中文网字计划在 Google Fonts 的切割方案的基础之上,对字体的使用顺序进行了排序分类,优化了各类字符的分包区间,并可使用更加快速的全球 CDN 服务,实现了近乎完美的中文字符落地方案。同时,计划中所开源的的开发工具流已经可以无缝融入前端开发,为中文字体在网络中的使用提供理论和技术上的支持。

建立自己的字体服务

上方介绍了三种不同的字体优化方式,现结合「中文网字计划」中的开源模块对字体进行优化

暂时无法在飞书文档外展示此内容

分析

这里取「阿里巴巴普惠体 3.0」进行测试,首先可以使用字体分析工具对字体进行分析

在线分析工具:https://chinese-font.netlify.app/analyze/

离线分析工具:https://www.npmjs.com/package/font-analyze

可以看出,在 AlibabaPuHuiTi-3-55-Regular 文件的版权信息,同时中文文字覆盖率信息很好,CJK 覆盖率一般

切割

@konghayao/cn-font-split 是一个基于 Node.js 的字体分包器,能够将来源字体文件分成多个包,并且提供附带成果预览和数据分析功能 。中文网字体计划使用 @konghayao/cn-font-split 作为核心,构建了一系列字体的分包成品。如果您需要对私有字体进行简单分包和静态部署,选择它再适合不过了。

在线切割工具

https://chinese-font.netlify.app/online-split/

在线工具可通过提交字体进行分包处理,借助 WebAssembly、多线程等技术优化,使得其可以运行在任何标准的 Nodejs 或者是 Web 环境中执行,这意味着所有现代浏览器都可以进行分包。

这里看到分包结果是以 woff2 进行输出的,同时分包后文件大小比源字体还小很多。原因如下:

在现代字体中,WOFF2 是最新的,拥有最广泛的浏览器支持,并提供最好的压缩。由于使用 Brotli,WOFF2 的压缩率比 WOFF 提高了 30%,从而减少了下载数据,从而提高了性能。

离线切割工具

https://www.npmjs.com/package/@konghayao/cn-font-split

安装

npm install @konghayao/cn-font-split

执行脚本
import { fontSplit } from '@konghayao/cn-font-split';
// import { fontSplit } from "@konghayao/cn-font-split/dist/browser/index.js";
// import { fontSplit } from "https://cdn.jsdelivr.net/npm/@konghayao/cn-font-split@4.3.6/dist/browser/index.js";
fontSplit({
    FontPath: './fonts/SourceHanSerifCN-Bold.ttf', // 部分 otf 文件会报错,最好使用 ttf 版本的字体
    destFold: './build',
    targetType: 'woff2', // ttf woff2;注意 eot 文件在浏览器中的支持度非常低,所以不进行支持
    chunkSize: 70 * 1024, // 如果需要的话,自己定制吧
    testHTML: true, // 输出一份 html 报告文件
    reporter: true, // 输出 json 格式报告
    // previewImage: {}, // 只要填入 这个参数,就会进行图片预览文件生成,文件为 SVG 格式
    threads: {}, // 建议开启多线程
    css: {
        // 覆盖默认的 css 设置,一般不需要进行更改
        // fontFamily: "站酷庆科黄油体",
        // fontWeight: 400,
    },
});

管理

font-server 是一个用于内网的字体存储和管理服务,支持通过 WebHook 对外通知信息,并允许外部程序通过端口进行内部数据访问。

主要功能包括:

  1. 用户可以上传原始字体文件,系统会保存这些字体文件。
  2. 触发打包字体功能后,切割服务器会自动获取内部存储的字体文件,并对其进行切割,然后将切割后的字体片段存入内部文件系统。
  3. 支持 WebHook 订阅功能,触发 hook 事件后,系统会广播订阅 url,通知外部程序相关事件信息。
  4. 在切割完成后,外部监听程序可以获取内部的切割分片,并将其部署到外部公开的 OSS 系统上。特别地,内外 OSS 系统应该使用相同的路径。
  5. 用户可以通过 OSS 系统提供的 CDN 加速访问字体文件,同时嵌入字体加载 HTML 片段,浏览器会自动加载相应的 CSS 文件和字体文件。
  6. 提供简单的 Admin 界面,方便用户进行可视化操作。

通过部署 font-server 服务可以便捷高效管理业务内字体

优化

现在拥有了分割后的字体,可直接上传到静态资源存储中进行使用了,接下来介绍提高字体加载速度的方式

  1. 切割分包大小适当:建议是设置 50-100KB 左右范围进行打包,这样单个包的大小不会太大,HTTP/2 的加载速度也够快。cn-font-split 的默认值是 70 KB 能够满足大多数场景。
  2. 使用支持并发加载的 CDN:开启 CDN 的 HTTP/2 支持
  3. 一定要配置 HTTP 缓存条件:在有缓存时,用户打开你的网站是可以达到 50ms 内瞬间加载完所有字体包的。由于字体文件配置一次就基本上不会进行改动,所以可以持久缓存。
  4. 文档站点的 预加载:如果网站有条件,可以在首页或者是所有页面,在浏览器空闲的时候,使用 js 的 fetch (force-cache) 请求所有的字体包。这样浏览器会把字体都加入进缓存中,从而保证其它页面的文字也能迅速加载。至于分包的具体名称,可以使用 reporter.json 文件查看。

请勿使用 Preload 预下载 CSS 文件

Preload 预下载会全量下载对应文件,这样会导致字体按需下载失效。但是你可以预加载几个常用的字体文件分片,这个需要你手动去判断加载,流程较为复杂。

其他问题

  • 字体文件下载抢占 JS 请求问题: 字体文件如果在入口 HTML 文件中加载,那么浏览器会查看 HTML 中需要使用的字,并加载字体,但是在 JS 中使用数据请求就会出现问题。已经发出的字体下载占用了浏览器的下载并发数,进而推迟 JS 下载。建议是使用 JS 添加 link 标签动态导入 css 的方式延迟大概 150ms 即可。
  • 强制使用分包时,源字体没有某些 字形 ,导致一个包内没有被分满:使用一个只有大致 6373 字符的字体,但是采用 Noto-Serif-SC 分包策略,那么部分包内会有缺失字体的现象,这是正常的。这个特性,插件将不会进行干涉。建议较全的字体包可以使用 Google 字体的中文分包方式,而小字体包使用自动分包策略就好了。

参考资料


shoyuf
660 声望33 粉丝

Web Developer