You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用网页字体时如何避免FOUT(无样式文本闪烁)问题?

解决方案

现有代码的核心问题是执行顺序错误:在Google Font的CSS样式表加载完成前就调用了document.fonts.load(),此时浏览器还没有解析到对应字体的@font-face规则,load()方法会优先匹配本地安装的同名字体直接触发回调,等后续CSS加载完成、实际网络字体开始下载时,回调已经执行完毕触发了样式切换,就会出现FOUT。

修正步骤

  • 先给link元素绑定load事件,等Google Font的CSS文件加载、解析完成,@font-face规则注册到文档后,再触发字体加载逻辑
  • 给document.fonts.load()传入第二个参数作为测试文本,避免字体包含特殊字符集时加载判断异常
  • 额外判断font.status状态,确保字体完全加载后再执行回调

修正后代码

function requestGoogleFont(fontFamily, fontWeight, fontStyle, doOnLoad) {
    let fontDesc = [fontStyle, fontWeight, '14px', fontFamily + ', ', 'sans-serif'].join(' '),
        headElement = pageFrameContents.head,
        fontVariant = fontStyle === 'italic' ? fontWeight + 'italic': fontWeight,
        url = 'https://fonts.googleapis.com/css?family=' + fontFamily.split(' ').join('+') + ':' + fontVariant,
        link = html.createAndAppend(headElement, '<link rel="stylesheet">'); 

    fontLoadInitiator.style.font = fontDesc;
    // 等待CSS加载完成,@font-face规则注册后再加载字体
    link.onload = function() {
        const frameDoc = pageFrame.contentWindow.document;
        // 传入测试文本,有特殊字符需求可自行调整
        frameDoc.fonts.load(fontDesc, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
            .then(function() {
                // 二次校验字体是否确实加载完成
                const isLoaded = frameDoc.fonts.check(fontDesc);
                if (isLoaded) {
                    doOnLoad();
                }
            });
    }
    link.setAttribute("href", url);
}

额外优化方案

如果要彻底消除FOUT的感知,可以在字体加载完成前给iframe内容设置临时的visibility: hidden,等回调执行后再恢复可见,比定时器方案更准确,不会出现额外的等待时长。


内容的提问来源于stack exchange,提问作者Stephen Miller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 03:06:02