如何避免由 Web 字体引起的布局偏移( 三 )


cache-control: max-age=31536000,immutable这告诉浏览器他们可以保留字体长达一年并且不需要重新验证( Firefox 和 Safariimmutable 支持,Chrome 应该自动避免重新验证请求) 。避免将 ETag 添加到这些响应中,因为它们可能会强制重新验证 。
还要检查您的 Content Delivery Network 配置是否可以将字体文件存储在缓存中,较旧的配置可能不包含.woff2扩展名,从而导致原始命中并减慢响应速度 。
使用预加载一般来讲浏览器不会随便地去下载字体文件,它们会等到渲染树构建完成后才能知道需要哪些字体 。这意味着仅在浏览器下载并解析 HTML 和 CSS 时,即在呈现文本之前,才请求 Web 字体 。但需要注意的是,内联 CSS 不需要网络请求,这意味着我们的字体可以在页面加载的早期获取 。

如何避免由 Web 字体引起的布局偏移

文章插图
渲染树的构建过程会阻塞Web字体的请求 。
但是如果我们确定页面文本的渲染肯定会用到一些网络字体时,我们可以使用preload让浏览器提前下载字体文件 。
【如何避免由 Web 字体引起的布局偏移】<link rel="preload" href=https://www.huyubaike.com/biancheng/"./public/fonts/汉仪旗黑.woff2" crossorigin="anonymous" type="font/woff2">当浏览器解析这行 HTML 时,它会立即发送一个对字体文件的高优先级请求 。
但是需要注意的是,预加载的请求会占用其它请求的带宽,所以我们在使用过程需要考虑清楚是否值得这么做 。
将字体转为Base64还有一种常用的方法是将字体作为 Base64 字符串嵌入到 CSS 中,从而无需额外的字体请求并确保在呈现文本时字体可用 。
但这个方法也不是绝对的好方法,它只适合一些小型字体文件,例如上面提到的使用font-spider提取后的字体文件,并且该字体文件足够小,因为将字体文件转化为Base64字符串往往会增加体积 。
一般来讲它有以下缺点:
  1. 字体文件是压缩的二进制对象,编码为 Base64 字符串会显着增加大小 。CSS 包的 gzip 或 brotli 压缩并不能完全弥补这种膨胀 。
  2. 字体将被发送到每个浏览器,即使有的浏览器不能使用
  3. 字体很少更改,但 CSS 经常更改,这将降低字体的缓存效率,因为每次 CSS 更改都会使整个包无效
  4. 膨胀 CSS 大小几乎肯定会延迟页面渲染
使用f-mods减少布局偏移F-mods 是对字体描述符规范的提议更新,其中包括四个新的描述符:
  • ascent-override (%) : 覆盖分配给上升器的大小
  • descent-override (%) : 覆盖分配给下降者的行高
  • line-gap-override (%) : 覆盖行间距
  • advance-override (#) : 为每个字符设置一个额外的提前量,以帮助匹配行宽并防止单词溢出
前三个都影响线的高度:线框高度 = 上升 + 下降 + 线间隙 。基线位置 = 线框顶部 + 线间隙 / 2 + 上升 。
这四个描述符的组合允许我们通过告诉浏览器在下载 Web 字体之前字符将占用多少空间来覆盖备用字体的布局以匹配 Web 字体 。
f-mods 只真正修改垂直间距和定位 。这意味着仍然需要处理字符间距和字母间距,否则可能会在不同的点出现断行的单词,从而导致元素高度发生变化,从而导致布局发生变化 。但是@font-face 声明中没有letter-spacingandword-spacing属性,因此我们必须在主体或元素上声明 。
@font-face {  font-family: custom-font;  src: url("./public/fonts/汉仪旗黑.woff2");}@font-face {  font-family: fallback-font;  src: local(Arial);  ascent-override: 100%;  descent-override: 20%;  line-gap-override: normal;  advance-override: 10;}/* 这些具体数值因字体而已,需要按照自己的字体进行计算调整*/body {  font-family: custom-font, fallback-font;}.content {  letter-spacing: -1.1px;  word-spacing: -0.2px;}

经验总结扩展阅读