在呈现网页之前等待加载字体

时间:2011-01-17 10:42:51

标签: css fonts font-face

我正在使用@ font-face在我的网站中嵌入字体。首先,文本呈现为系统默认值,然后(一旦字体文件可能已加载),正确的字体稍后呈现一小段时间。有没有办法最小化/摆脱这种延迟,通过延迟页面渲染,直到字体加载或类似。

11 个答案:

答案 0 :(得分:16)

这取决于浏览器的行为方式。

首先,你的@font声明在哪里?它是否与您的HTML内联,在页面上的CSS工作表中声明,或者(希望)在外部CSS工作表中声明?

如果它不在外部工作表中,请尝试将其移动到一个(通常这是更好的做法)。

如果这没有帮助,你需要问自己是第二个差异的一小部分真的对用户体验有显着的不利影响吗?如果是,那么考虑JavaScript,你可以做一些事情,重定向,暂停等,但这些可能实际上更糟比原始问题。对用户来说更糟糕,更糟糕的是维护。

此链接可能有所帮助:

http://paulirish.com/2009/fighting-the-font-face-fout/

答案 1 :(得分:15)

修改:最佳方法可能是 base64编码字体。这意味着您的字体必须在解析和显示HTML时完全加载。您可以使用font squirrel的webfont生成器https://www.fontsquirrel.com/tools/webfont-generator通过单击“Expert”然后单击“base64 encode”来执行此操作。这就是TypeKit等服务的工作原理。


原始回答: 另一种检测是否加载字体的方法是使用FontLoader https://github.com/smnh/FontLoader或复制其策略。

它们绑定到浏览器中的scroll事件,因为当加载字体时,它将调整文本的大小。它使用两个包含div(当高度改变时将滚动)和IE的单独回退。

另一种方法是使用setInterval定期检查DOM,但使用javascript事件要快得多且优越。

显然,你可以做一些事情,比如将body的不透明度设置为0,然后在字体加载后显示它。

答案 2 :(得分:5)

Joni Korpi有一篇关于在页面其余部分之前加载字体的文章。

http://jonikorpi.com/a-smoother-page-load/

他还使用了loading.gif来缓解延迟,因此用户不会感到沮丧。

答案 3 :(得分:4)

只有IE首先加载字体,然后加载页面的其余部分。 其他浏览器出于某种原因同时加载内容。想象一下,托管字体的服务器或字体下载存在问题。 您将挂起整个站点,直到加载字体。在我看来,一缕没有风格的文字比没有看到网站更好

答案 4 :(得分:4)

此代码对我来说效果很好。它使用Font Loading API,它在现代浏览器中具有良好的支持。

<style>
  @font-face {
    font-family: 'DemoFont';
    font-style: normal;
    font-weight: 400;
    src: url("./fonts/DemoFont.eot");
    src: url("./fonts/DemoFont.woff2") format("woff2"),
    url("./fonts/DemoFont.woff") format("woff"),
    url("./fonts/DemoFont.ttf") format("truetype");
  }

  .font {
    font-family: 'DemoFont';
    color: transparent;
  }

  html.font-loaded .font {
    color: inherit; // Override `transparent` from .font
  }

</style>
<script>
  // Check if API exists
  if (document && document.fonts) {    
    // Do not block page loading
    setTimeout(function () {           
      document.fonts.load('16px "DemoFont"').then(() => {
        // Make font using elements visible
        document.documentElement.classList.add('font-loaded') 
      })
    }, 0)
  } else {
    // Fallback if API does not exist 
    document.documentElement.classList.add('font-loaded') 
  }
</script>

技巧是使用字体将CSS颜色设置为透明。加载后,可以通过向font-loaded元素添加<html>类来重置它。

请为您的项目有意义的内容替换DemoFont,以使其正常工作。

答案 5 :(得分:3)

使用https://github.com/typekit/webfontloader

并检查配置中的事件 https://github.com/typekit/webfontloader#configuration

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script>
    WebFont.load({
        custom: {
            families: [ "CustomFont1", "CustomFont2" ]
        },
        active: function() {
            //Render your page
        }
    });
</script>

答案 6 :(得分:1)

您可以在@ font-face中使用CSS font-display。 所有可用值的关键字为:

  • auto
  • swap
  • 回退
  • 可选的

Giulio Mainardi撰写了一篇关于所有这些文章的精彩文章,你应该在sitepoint上使用它。

您可以在此处阅读:https://www.sitepoint.com/css-font-display-future-font-rendering-web/?utm_source=frontendfocus&utm_medium=email

答案 7 :(得分:1)

由于没有人提到,我认为这个问题需要更新。我设法解决此问题的方法是使用现代浏览器支持的“预加载”选项。

以防有人不需要支持旧的浏览器。

<link rel="preload" href="assets/fonts/xxx.woff" as="font" type="font/woff" crossorigin>

一些有用的链接,其中包含更多详细信息:

https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content http://www.bramstein.com/writing/preload-hints-for-web-fonts.html

答案 8 :(得分:1)

在渲染到HTML画布时遇到类似的问题,这是我的解决方案。它基于FontFace API,与Holtwicks方法类似。主要区别在于,这是一种通用方法,对于外部字体/样式表(例如Google字体),它是开箱即用的。

一些注意事项; 如果字体未知,fonts.load( ... )会很高兴地使用一组空字体解决。据推测,如果在添加字体的样式表之前调用此代码,就会发生这种情况。我添加了fonts.check(...)来克服这个问题。

这将使您等待JavaScript执行,直到字体可用为止,因此对于“常规” HTML内容开箱即用。您可以将其与上述Holtwicks答案结合。

export async function waitForFontLoad(
    font: string,
    timeout = 1000,
    interval = 10
) {
    return new Promise((resolve, reject) => {
        // repeatedly poll check
        const poller = setInterval(async () => {
            try {
                await document.fonts.load(font);
            } catch (err) {
                reject(err);
            }
            if (document.fonts.check(font)) {
                clearInterval(poller);
                resolve(true);
            }
        }, interval);
        setTimeout(() => clearInterval(poller), timeout);
    });
}

答案 9 :(得分:-4)

(function() {
        document.getElementsByTagName("html")[0].setAttribute("class","wf-loading")
        document.getElementsByTagName("html")[0].setAttribute("className","wf-loading")
    })();

使用此方法..与Webfont.js一起使用

答案 10 :(得分:-5)

也许是这样的:

$("body").html("<img src='ajax-loader.gif' />");

然后当页面加载时,将主体的内容替换为实际内容,并希望完全呈现的字体,你可能不得不玩这个... ...