预加载@ font-face字体?

时间:2009-08-25 20:35:49

标签: javascript css fonts embedding font-face

是否有可能在页面加载之前预加载或以其他方式缓存@ font-face字体(很可能是使用javascript),这样当页面最终加载时你不会得到那个丑陋的跳转?

14 个答案:

答案 0 :(得分:30)

一种简单的技术是将它放在索引中的某个位置:

<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 :(得分:23)

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

主要是欺骗浏览器尽快下载文件..

您也可以将其作为数据uri提供,这有很大帮助。 并且你可以隐藏页面内容并在准备就绪时显示它。

答案 2 :(得分:18)

2017:您现在拥有preload

  

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="horizontal"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_weight="100"
  android:gravity="center"
  android:layout_gravity="center"
  xmlns:android="http://schemas.android.com/apk/res/android">
  <EditText
    android:background="#00000000"
    android:singleLine="true"
    android:maxLength="2"
    android:inputType="number"
    android:gravity="bottom"
    android:hint="00"
    android:cursorVisible="false"
    android:textColorHint="#2f8677"
    android:textColor="#2f8677"
    android:textSize="40sp"
    android:id="@+id/txtMinutes"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<TextView
    android:gravity="top"
    android:text=":"
    android:textSize="40dp"
    android:textColor="#2f8677"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<EditText
    android:background="#00000000"
    android:singleLine="true"
    android:maxLength="2"
    android:inputType="number"
    android:gravity="bottom"
    android:hint="00"
    android:cursorVisible="false"
    android:textColorHint="#2f8677"
    android:textColor="#2f8677"
    android:textSize="40sp"
    android:id="@+id/txtSeconds"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<TextView
    android:layout_gravity="center"
    android:text=":"
    android:textSize="40dp"
    android:cursorVisible="false"
    android:textColor="#2f8677"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<EditText
    android:background="#00000000"
    android:singleLine="true"
    android:maxLength="2"
    android:inputType="number"
    android:gravity="bottom"
    android:hint="00"
    android:textColorHint="#2f8677"
    android:textColor="#2f8677"
    android:textSize="40sp"
    android:id="@+id/txtTimerMicroSeconds"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

检查browser compatibility

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

讨论其他技术的优缺点here(不是我的博客)。

答案 3 :(得分: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's hulking Webfont Loader

更简单,更轻巧

这是Font.js的github仓库:

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

答案 4 :(得分:3)

This应该可以解决您的问题。

回答您的初步问题:是的,您可以。目前只有Gecko和WebKit浏览器支持它 您只需在脑中添加链接标记:

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

答案 5 :(得分:3)

避免 FOIT:不可见文本的闪烁

当然,第一步是在 HTML 中预加载字体:

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

请注意,字体总是在启用 cross-origin resource sharing (CORS)even though the font resides on the same server 的情况下预加载:

<块引用>

当预加载在启用 CORS 的情况下获取的资源(例如 fetch()、XMLHttpRequest 或字体)时,需要特别注意在元素上设置 crossorigin 属性。需要设置该属性以匹配资源的 CORS 和凭据模式,即使提取不是跨域的也是如此。

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

对于可选的 type="MIME-type" 属性,情况并非如此。 between browsers 和机构对于 MIME-type 字体应该是什么存在很多不一致。如果某个浏览器指定了错误的类型,则不会预加载字体文件。因此,不要使用 type="MIME-type" HTML 属性。

然后是 FOIT,flash of invisible text。 在现代浏览器中,此 can easily be avoided@font-face CSS 声明中通过添加 font-display: swap; 属性。

@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;
}

答案 6 :(得分:2)

我通过在主文档中添加一些字母并使其透明并指定了我想要加载的字体来完成此操作。

e.g。

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

答案 7 :(得分:1)

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

答案 8 :(得分:0)

我不知道任何当前的技术可以在字体加载时避免闪烁,但是您可以通过为字体发送适当的缓存标头并确保该请求尽快通过来最小化它。

答案 9 :(得分:0)

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

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

我在最近的文章http://rezoner.net/preloading-font-face-using-canvas,686

中对此技术进行了一些解释

答案 10 :(得分:0)

Google有一个很好的图书馆:https://developers.google.com/webfonts/docs/webfont_loader 您几乎可以使用任何字体,lib会将类添加到html标记中。

甚至可以在加载和激活certrain字体时为您提供javascript事件!

不要忘记为你的fontfiles gzipped服务!它肯定会加快速度!

答案 11 :(得分:0)

使用标准CSS Font Loading API

等待( all )要加载的字体,然后显示您的内容:

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

Demo CodePen

答案 12 :(得分:0)

我发现最好的方法是预加载包含字体的样式表,然后让浏览器自动加载它。我在其他位置(在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之前的字体,因此看不到字体更改效果。

答案 13 :(得分:0)

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

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