预载@font-face 字体?

有没有可能在页面加载之前预加载或缓存@font-face 字体(很可能是用 javascript) ,这样当页面最终加载时就不会出现那种难看的跳转?

164508 次浏览

这个答案不再是最新的

请参考这个更新的答案: https://stackoverflow.com/a/46830425/4031815


反对回答

我不知道当前有什么技术可以在字体加载时避免闪烁,但是您可以通过为字体发送适当的缓存头文件并确保请求尽可能快地完成来最小化闪烁。

这个 应该可以解决你的问题。

为了回答你最初的问题: 你可以的。目前只有 Gecko 和 WebKit 浏览器支持它。
你只需要在头脑中添加链接标签:

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

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

主要是欺骗浏览器以最快的速度下载文件。

您也可以将其作为数据-uri 提供,这很有帮助。 你也可以隐藏页面内容,并在准备好时显示出来。

为此,我在主文档中添加了一些字母,使其透明,并分配了我想要加载的字体。

例如:。

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

最近,我正在开发一款游戏,它与 CocoonJS 兼容,DOM 仅限于画布元素——以下是我的方法:

在没有加载字体的情况下,使用 filText 可以正常执行,但是没有视觉反馈——这样画布平面就会保持完整——所有你需要做的就是定期检查画布,看看当字体加载正确时会发生什么变化(例如,循环遍历 getImageData 搜索任何不透明的像素)。

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

谷歌为此提供了一个很好的图书馆: < a href = “ https://developers.Google.com/webfonts/docs/webfont _ loader”rel = “ nofollow”> https://developers.Google.com/webfonts/docs/webfont_loader 您几乎可以使用任何字体,而且 lib 将向 html 标记添加类。

它甚至在某些字体加载和激活时为您提供 javascript 事件!

不要忘记提供你的字体文件压缩! 它一定会加快速度!

正确的字体预加载是 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");
}

它比 谷歌庞大的 Webfont Loader更简单、更轻便

下面是 Font.js 的 github 回购:

Https://github.com/pomax/font.js

一个简单的技巧就是把它放在你的索引中:

<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上进行了测试

通过谷歌的 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
}
}
});

自2017年以来,你已经有了一个预加载

MDN: 元素的 rel 属性的预加载值允许您 在 HTML 中编写声明性获取请求,指定 页面在加载后很快就需要的资源,这些资源 因此希望在页面生命周期的早期就开始预加载 在浏览器的主要渲染机器启动之前加载 确保它们能够更早地提供,而且不太可能 阻止页面的第一次渲染,从而导致性能的提高。

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

一定要检查 浏览器兼容性

它对于字体预加载最有用(而不是等待浏览器在某些 CSS 中找到它)。你也可以预载一些标志,图标和脚本。

使用标准的 字体加载 API

等待(所有)加载字体,然后显示内容:

document.fonts.ready.then((fontFaceSet) => {
console.log(fontFaceSet.size, 'FontFaces loaded.');
document.getElementById('waitScreen').style.display = 'none';
});

演示 CodePen

我发现最好的方法是预加载一个包含字体的样式表,然后让浏览器自动加载它。我在其他位置(在 html 页面中)使用了字体-face,但随后我可以简要地观察字体变化的效果。

<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 来给字体分配名称。尽管可以通过 link 标记加载字体,但是不推荐这样做,因为不能为带有 link 标记的字体分配名称。如果没有像 font-face 那样的名称,你就不能在网页的任何地方使用它。根据 gtmetrix,样式表在开始加载,然后按顺序加载其余的脚本/样式,然后加载 dom 之前的字体,因此不会看到字体更改效果。

你的头部应该包括如下预加载轴:

<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');
}

避免 FOIT: 隐形文本的闪烁

毫无疑问,第一步是预加载 HTML 中的字体:

<link rel="preload" href="pacifico.woff2" as="font" crossorigin="anonymous">

请注意,字体总是预加载 跨来源资源共享(CORS)启用,即使字体位于同一台服务器上:

当预加载启用 CORS 获取的资源(例如 get ()、 XMLHttpRequest 或者字体)时,需要特别注意在元素上设置 cross sorigin 属性。需要将属性设置为匹配资源的 CORS 和凭据模式,即使提取不是跨源的。

因此,crossorigin="anonymous"属性是绝对必要的。

对于可选的 type="MIME-type"属性则不能这样说。关于 MIME 类型的字体应该是什么,浏览器之间和机构之间有很多不一致之处。如果为某个浏览器指定了错误的类型,则不会预加载字体文件。因此,最好避免同时使用 type="MIME-type" HTML 属性。

然后,就是酷孩子们所说的 FOIT: 不可见文字的闪光。 在现代浏览器中,这个 FOIT 可以很容易地避免是通过将 font-display: swap;属性添加到 @font-face CSS 声明中来实现的。

@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
src: local('Pacifico Regular'), local('Pacifico-Regular'), url(pacifico.woff2) format('woff2');
font-display: swap;
}

找到放入 link标记的 href是困难的部分,我在 这篇文章中详细解释了它