Web 字体加载对 DOM 位置的影响
内容列表
由于公司的业务会用到自己设计师定制的 Web 字体,所以一般在组件开发过程中会利用 CSS 引用该字体(@font-face),前段时间发现一个线上问题:在部分 iOS 机型上,DOM 元素的位置发生了错位。
首先,对于问题复现的必要条件做了分析,为以下几个方面
- 部分 iOS 机型(新旧机型均有)
- 问题发生在首次页面加载时(即后续加载问题不再复现)
根据以往的经验和代码实现来看,必然是 DOM 测量的尺寸数据不准确导致的,于是首先尝试加了延迟的方案看看效果,发现问题依然存在,然后尝试线上调试看看具体测量到的 DOM 尺寸数据是否准确。由于线上调试比较麻烦,所以也更进一步分析为何问题出现在清除缓存后的首次加载,推测是什么资源加载太慢导致的?但当时由于着急,主要考虑的都是显式引入的资源(例如 js、css 文件等,忽略了一些细节),在这方面也没有什么进展。于是,继续尝试线上调试,结果发现首次加载和二次加载得到的 DOM 测量数据完全一致,此时这个问题就有点“邪门”了,难道是浏览器内核渲染的问题?Google 了很久,也没有什么收获,但由于对线上用户不是很大,就暂时搁置了这个问题,暂且认为是浏览器内核的一个什么 bug(虽然说这个确实没有什么说服力,但苦于花了很多精力和时间依然找不到原因,考虑到解决这个问题的性价比不高就先放弃了)。
当然,之所以写这篇文章也是为了记录导致这个问题的真正原因和解决方案。后来,有个同事提到之前的文档有记录过类似因为公司定制字体加载导致的页面问题,简单看了下文档后,发现之前确实忽略了这个细节(字体文件通常比较大,加载比较慢,但由于是放在 CDN 上的所以一直没太在意)。经过和业务侧的前端沟通后,一天下午抽空尝试了下,发现确实是由于 Web 字体资源太大(CDN 不太稳定)加载较慢导致的 DOM 位置渲染错位(需要注意的是,该原因并没有导致 DOM 测量出现错误)。这里贴一下解决该问题的示例代码:
document.fonts.ready.then(() => {
this.resize();
});
Web 字体加载快慢没有对 DOM 测量的数据准确性产生影响,也是在视觉效果会有影响(导致 DOM 位置错位)。这个问题场景以前没有遇到过,其原因和解决该问题所用到的 API 也比较冷门,所以在此记录一下。