H5字体加载策略优化

随着网页内容的丰富化,我们使用自定义字体来处理漂亮个性化的网页呈现,所以我们会在网页中使用自定义字体,但是也伴随着给我们带来了一些问题,那就是自定义字体比较大,尤其是中文字体,随便就是好几兆,会给用户一种网页加载很慢的感觉,所以针对上述的问题需要做一部分优化:

下面是我项目使用的一些字体的大小:

image.png

1、设置 font-display: swap

我们需要在美观和性能之间做一个取舍和平衡点,查看MDN,可以通过font-display的设置去处理;

参考链接:https://developer.mozilla.org/zh-CN/docs/Web/CSS/@font-face/font-display

下表是不同font-display加载速度的对比以及描述:

选项 备用字体显示顺序 真实字体显示顺序 说明
auto 1 1 字体显示策略由用户代理(浏览器)定义,可能是其他4种的一种,很多浏览器默认的是block。
block 3 1 为字体提供一个短暂的阻塞周期(3s)和无限的交换周期。
这个短暂的阻塞周期一般是3s,在这3s,自定义字体部分是空白的,iOS默认就是这个选项,导致一进去页面就是空白的。
swap 1 1 为字体提供一个非常小的阻塞周期(<=100ms)和无限的交换周期。
能很快的展示备用字体,并且等待自定义字体加载完成之后会使用自定义的字体,不管多久加载出来都会替换。
fallback 1 没显示 为字体提供一个非常小的阻塞周期(<=100ms)和短暂的交换周期(3s)。
和swap类似,但是如果字体加载太慢,时间超过了阻塞周期+交换周期的时间,自定义字体将永远不会显示。
optional 1 没显示 为字体提供一个非常小的阻塞周期(<=100ms),并且没有交换周期。
在阻塞周期内字体没有加载完成,自定义字体永远不会显示。
基本上不会导致页面闪动,但是并不会取消下载字体。

不同font-display对应的加载时间线

  • 黑色代表页面上不展示内容的时间
  • 红色代表展示备用字体的时间
  • 蓝色代表展示自定义字体的时间

image.png

通过上面的图可以看到,swap基本不会有展示空白字体的时间,在没有加载完成的时候页面展示的备用字体。

上面提到三个概念:字体阻塞周期、字体交换周期、字体失败周期,加载自定义字体都会经历下面三个阶段,上面设置的font-display相当于配置了每个阶段的时长。

下图展示了加载一个自定义字体的过程。

image.png

字体阻塞周期(Block)
如果未加载字体,任何试图使用它的元素都必须渲染不可见的后备字体。如果在此期间字体已成功加载,则正常使用它。在此期间特殊字体部分会展示空白或者错误的字体样式,如果是字体图标就会出现奇怪的符号。

字体交换周期(Swap)
如果未加载字体,任何尝试使用它的元素都必须呈现后备字体。如果在此期间字体已成功加载,则正常使用它。

字体失败周期(Fail)
如果未加载字体,用户代理将其视为导致正常字体回退的失败加载。

使用场景

  • 如果字体是用来展示主网页的字体,特殊字体只是装饰性作用的,防止闪动,建议使用optional。
  • 如果是客户指定的字体,必须要展示,可以使用swap,在没有加载出来的时候展示备用字体。
  • 如果字体是用来展示图标的,建议使用block,在没有加载的时候不展示字体。

2、字体子集化方案 Fontmin,subfont

对于页面中出现的固定文本,可以在字体文件中拆出来,只加载必须要的字体,这样通过裁剪之后的字体的尺寸会大大减少;

可以使用fontmin的Node.js API直接和webpack集成,乐活动模板已经集成。

image.png


参考链接

留下回复