别调P
文章14
标签39
分类14
前端字体大小解决方案——字体切片

前端字体大小解决方案——字体切片

前端字体文件过大问题

在中文网站中,字体文件往往是最大的文件,每次请求网站都会下载字体文件,这样会导致网站加载速度变慢,影响用户体验。

在这方面,谷歌字体使用字体“切片”技术,将字体文件切割成多个小文件,使用 unicode-range 按需加载,这样可以减少字体文件的大小,提高网站加载速度。

unicode-range

unicode-range 是 CSS3 中的一个属性,用于指定字体文件中包含的字符范围,浏览器会根据这个属性来判断是否需要下载字体文件。

unicode-range 属性的值可以是一个或多个范围,每个范围之间用逗号分隔,每个范围可以是一个或多个字符,每个字符之间用连字符分隔。

例如引入谷歌字体的 Noto Sans SC,可以使用以下代码:

@font-face {
  font-family: 'Noto Sans SC';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/notosanssc/v12/k3kXo84MPvpLmixcA63oeALhLOCT-xWNm8Hqd37g1OkDRZe7lR4sg1IzSy-MNbE9VH8V.4.woff2) format('woff2');
  unicode-range: U+1f1e9-1f1f5, U+1f1f7-1f1ff, U+1f21a, U+1f232, U+1f234-1f237, U+1f250-1f251, U+1f300, U+1f302-1f308, U+1f30a-1f311, U+1f315, U+1f319-1f320, U+1f324, U+1f327, U+1f32a, U+1f32c-1f32d, U+1f330-1f357, U+1f359-1f37e;
}
...

字体切片

字体切片是指将字体文件切割成多个小文件,每个文件包含不同的字符,这样可以减少字体文件的大小,提高网站加载速度。

谷歌采用机器学习等手段,将字体文件切割成多个小文件,每个文件包含不同的字符,这样的话,一般网页中使用到的中文也只是一部分字体,只需要加载多个资源包就能完全覆盖。就算网页中有很多生僻字,需要付出的代价也只是多加载几个资源包。

字体切片工具

font-slice

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

字体切片使用

安装

npm install --save-dev font-slice
# or
yarn add -D font-slice

使用

const fontSlice = require('font-slice');
const createFontSlice = require('font-slice');

createFontSlice({
  // 字体文件
  fontPath: path.resolve(__dirname, 'YourFont.ttf'),
  // 输出文件夹
  outputDir: path.resolve(__dirname, './output'),
})

这是一个简单的使用示例。使用 NodeJS 运行此文件,即可在 ./output 文件夹中生成切片后的字体文件,同时有一个 CSS 文件,可直接调用 CSS 使用。

配置项

declare type TOptions = {
  /**
   * 需要处理的源字体,暂只支持 ttf、otf (otf 也是先转成 ttf 再处理)
   */
  fontPath: string;
  /**
   * 保存到的目录
   */
  outputDir: string;
  /**
   * 是否需要在生成完成后打开预览页面,默认为 true,如果为 false 不会生成 index.html 及启动服务器
   */
  preview?: boolean;
  /**
   * 生成字体文件的名称,默认为 `${fontFileName}.${index + 1}`
   */
  generateFontSubsetName?: (fontFileName: string, index: number) => string;
  /**
   * 需要转换到的格式,默认为 ["woff2"]
   */
  formats?: Array<'woff' | 'woff2' | 'ttf' | 'eot' | 'svg'>;
  /**
   * 字体的 font-family 值
   */
  fontFamily?: string;
  /**
   * 字体的 font-weight,默认为 normal
   */
  fontWeight?: string;
  /**
   * 字体的 fontStyle,默认为 normal
   */
  fontStyle?: string;
  /**
   * 字体的 font-display,默认为 swap
   */
  fontDisplay?: string;
  /**
   * 自定义字体的分割格式,默认为 google fonts 的 unicode-range
   */
  customUnicodeRange?: Array<{
    unicodes: number[];
  }>;
  /**
   * 如果开启可能会让生成的字体体积变大,默认不开启
   * keep ttf hint info (fpgm, prep, cvt). default = false
   * https://github.com/ecomfe/fontmin#glyph
   */
  hinting?: boolean;
};

参考

中文字体的终极解决方案——对字体进行切片

本文作者:别调P
本文链接:https://blog.bietiaop.com/2023/06/29/web/front/css/zi-ti-qie-ge-jian-shao-zi-ti-da-xiao/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×