处理页面引入字体问题 123
在实际开发中,经常会遇到活动页面引入特殊字体的情况,那么如何高效的引入页面字体,但又不影响页面加载就是一个必须解决的问题,特别在某些情况下会造成一些视觉闪烁的情况。 分为两种处理路径,
- 一是缩小字体包大小,尽快提升自提的加载
- 二是更改字体的加载方式
缩小字体包大小
使用font-spider 提取字体
bash
// 安装font-spider
npm install font-spider -g
// 提取字体
font-spider font-spider/*.html使用 font-min 压缩字体
js
// 安装font-min
var Fontmin = require("fontmin");
var fontmin = new Fontmin()
.src("*.ttf")
.use(
Fontmin.glyph({
text: "Hello World 你好",
}),
)
.dest("build/font-min");
fontmin.run(function (err, files) {
if (err) {
throw err;
}
});使用 subset-font 子集字体
js
const subsetFont = require("subset-font");
const fs = require("fs");
const font = fs.readFileSync("./AliPuHui.woff2");
subsetFont(font, "Hello 你好", {
targetFormat: "woff2",
}).then((result) => {
fs.writeFileSync("build/AliPuHui.woff2", result);
});以上三种方式都可以缩小字体包大小,但是 font-spider 提取字体的方式会改变字体的原始字符集,而 font-min 压缩字体的方式会改变字体的字符集,而 subset-font 子集字体的方式不会改变字体的字符集。 如果想动态加载字体,基本是不可能的,因为大多数场景数据都是请求接口下发下来的
更改字体的加载方式
使用 link 标签提交加载
告诉浏览器提前加载字体文件,避免阻塞页面渲染。在 JS 还没执行之前就开始下载、优先级高、字体更早到达
html
<link
rel="preload"
href="build/AliPuHui.woff2"
as="font"
type="font/woff2"
crossorigin
/>font-display属性
| 值 | 阻塞期(Block Period) | 交换期(Swap Period) | 加载失败后表现 | 视觉效果 | 适用场景 |
|---|---|---|---|---|---|
| auto | 浏览器决定(通常≈block) | 浏览器决定 | 由浏览器决定 | 通常类似 block | 不关心字体加载策略时 |
| block | 有阻塞期(≈3 秒) | 无限交换期 | 超时后显示后备字体,加载完成再替换 | 可能出现“空白闪烁” | 品牌字体必须优先展示 |
| swap | 几乎无阻塞期 | 无限交换期 | 一直可替换 | 先显示后备字体,再闪一下 | 推荐用于大多数 Web 项目 |
| fallback | 很短(≈100ms) | 有限交换期(≈3 秒) | 超过时间后不再替换 | 几乎无空白,可能不替换 | 对闪烁敏感但又想尝试加载 |
| optional | 很短(≈100ms) | 无交换期 | 不会再替换 | 基本不会闪烁 | 移动端、弱网优化 |
demo如下
html
<style>
@font-face {
font-family: "AliPuHui";
src: url("build/AliPuHui.woff2") format("woff2");
font-display: swap;
}
</style>