预加载@ font-face字体?


76

是否可以在页面加载之前预加载或以其他方式缓存@ font-face字体(最有可能使用javascript),以便在页面最终加载时不会出现难看的跳转?


2
您不能指定高度/行高以避免跳跃效应吗?
kangax



Answers:



42

由于2017年你有预紧

MDN:元素的rel属性的preload值允许您在HTML中编写声明性的获取请求,从而指定页面在加载后不久将需要的资源,因此,您希望在页面加载的生命周期中尽早开始预加载,然后浏览器的主要渲染机制就会启动。这确保了它们较早可用,并且不太可能阻塞页面的第一个渲染,从而提高了性能。

<link rel="preload" href="/fonts/myfont.eot" as="font" crossorigin="anonymous" />

始终检查浏览器的兼容性

这对于字体预加载(不等待浏览器在某些CSS中找到字体)最有用。您还可以预加载一些徽标,图标和脚本。



@IlpoOksanen现在添加了它
Christophe Roussy

但是如何为已加载的字体分配字体系列名称?
Don Dilanga

@DonDilanga我认为这是必须通过CSS执行的操作
Christophe Roussy

40

一种简单的方法是将其放在索引中:

<div class="font_preload" style="opacity: 0">
    <span style="font-family: 'myfontface#1font-family', Arial, sans-serif;"></span>
    <span style="font-family: 'myfontface#2font-family', Arial, sans-serif;"></span>
    ...
</div>

已在Chrome 34,Safari 7和FF 29和IE 11上进行测试


1
在我的情况下,这非常适合将字体预加载以供在fabricjs中使用。谢谢。
布兰登

23

这里有一些“预加载”的技术:http : //paulirish.com/2009/fighting-the-font-face-fout/

主要是诱使浏览器尽可能快地下载文件。

您也可以将其作为数据URI交付,这很有帮助。并且您还可以隐藏页面内容并在页面准备就绪时显示它。


3
不好意思,要进行深入研究,但我怀疑我不明白。博客文章上的提示似乎是关于在加载字体时隐藏文本,但是如果我只想让Chrome浏览器尽快加载它,而不是在遇到带有该字体的某些文本时该怎么办?我最好的选择是<head>中的隐藏div吗?
伊莱·罗斯

6

您的头部应包括如下的预紧力:

<head>
    ...
    <link rel="preload" as="font" href="/somefolder/font-one.woff2">
    <link rel="preload" as="font" href="/somefolder/font-two.woff2">
</head>

这样,woff2将由支持预加载的浏览器预加载,并且所有后备格式将按通常的方式加载。
而且您的CSS字体外观应与此相似

@font-face {
    font-family: FontOne;
    src: url(../somefolder/font-one.eot);
    src: url(../somefolder/font-one.eot?#iefix) format('embedded-opentype'),
    url(../somefolder/font-one.woff2) format('woff2'), //Will be preloaded
    url(../somefolder/font-one.woff) format('woff'),
    url(../somefolder/font-one.ttf)  format('truetype'),
    url(../somefolder/font-one.svg#svgFontName) format('svg'); 
}
@font-face {
    font-family: FontTwo;
    src: url(../somefolder/font-two.eot);
    src: url(../somefolder/font-two.eot?#iefix) format('embedded-opentype'),
    url(../somefolder/font-two.woff2) format('woff2'), //Will be preloaded
    url(../somefolder/font-two.woff) format('woff'),
    url(../somefolder/font-two.ttf)  format('truetype'),
    url(../somefolder/font-two.svg#svgFontName) format('svg');
}

最好在<link>中添加以下属性type =“ font / woff2”crossorigin以防止浏览器错误。否则,这是我的情况的最佳答案。
MartinG

5

正确的字体预加载是HTML5规范中的一个大漏洞。我已经仔细研究了所有这些内容,发现的最可靠的解决方案是使用Font.js:

http://pomax.nihongoresources.com/pages/Font.js/

您可以使用与加载图片相同的API来加载字体

var anyFont = new Font();
anyFont.src = "fonts/fileName.otf";
anyFont.onload = function () {
  console.log("font loaded");
}

Google笨拙的Webfont Loader更加简单,轻巧

这是Font.js的github存储库:

https://github.com/Pomax/Font.js


4

通过Google的webfontloader

var fontDownloadCount = 0;
WebFont.load({
    custom: {
        families: ['fontfamily1', 'fontfamily2']
    },
    fontinactive: function() {
        fontDownloadCount++;
        if (fontDownloadCount == 2) {
            // all fonts have been loaded and now you can do what you want
        }
    }
});

您上方的那个人比您早2年给出了完全相同的答案。我很好奇
vsync

我的答案仅是一个代码段,人们可以使用webfontloader加载多种字体。前面的答案对webfontloader进行了很好的介绍,但不包含任何代码片段。
拉赞·保罗

您应该已经编辑了它,而不是重复它,并添加了代码示例。在问题中重复几乎相同的答案是非常令人困惑和浪费的。
vsync

2

应该可以解决您的问题。

回答您的第一个问题:是的,您可以。虽然目前仅Gecko和WebKit浏览器支持它。
您只需要在头部添加链接标签:

<link rel="prefetch" href="pathto/font">
<link rel="prerender" href="pathto/page">

在页面上预呈现内容时应谨慎。它与预取不同。
kleinfreund 2014年

2
为什么prerender和不preload?它是一种字体,而不是HTML文件,没有任何可渲染的内容
vsync

2

我是通过在主文档中添加一些字母并使其透明并分配要加载的字体来实现的。

例如

<p>normal text from within page here and then followed by:
<span style="font-family:'Arial Rounded Bold'; color:transparent;">t</span>
</p>


1

我发现最好的方法是预加载包含字体的样式表,然后让浏览器自动加载它。我在其他位置(在html页面中)使用了字体,但是随后我可以短暂观察到字体更改的效果。

<link href="fonts.css?family=Open+Sans" rel="preload stylesheet" as="style">

然后在font.css文件中,指定以下内容。

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans Regular'), local('OpenSans-Regular'),
       url('open-sans-v16-latin-regular.woff2') format('woff2'); /*  Super Modern Browsers */
}

通过链接标记预加载字体时,无法为字体分配名称(如果我错了,请纠正我,我仍然无法找到方法),因此,您必须使用font-face将名称分配给字体。即使可以通过链接标记加载字体,也不建议您这样做,因为您无法为其指定名称。没有像字体一样的名称,您将无法在网页的任何地方使用它。根据gtmetrix的说法,样式表首先加载,然后按顺序加载其余脚本/样式,然后加载dom之前的字体,因此看不到字体更改效果。


0

最近,我正在开发与CocoonJS兼容的游戏,但DOM限于canvas元素-这是我的方法:

将fillText与尚未加载的字体一起使用将可以正常执行,但没有视觉反馈-因此画布平面将保持不变-您要做的就是定期检查画布是否有任何更改(例如,遍历getImageData搜索任何非透明像素),当字体正确加载时会发生这种情况。

我在最近的文章http://rezoner.net/preloading-font-face-using-canvas,686中对这种技术进行了更多解释


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.