使用“预加载”链接指令在 Chrome 中预加载字体

Posted

技术标签:

【中文标题】使用“预加载”链接指令在 Chrome 中预加载字体【英文标题】:Preloading fonts in Chrome with 'preload' link directive 【发布时间】:2017-07-25 19:07:04 【问题描述】:

preload 指令在 Chrome 中未按预期执行。下面是一个完整的 html 页面,可以在 Chrome 中打开以进行结果比较。它应该应用所有 5 种字体;相反,它只应用第一个预加载的字体,将第二个字体设为假斜体,并简单地将默认衬线替换为剩余的 3 个。

此外,在开发人员的控制台中,大约 3 秒后,对于五种字体中的每一种都会出现此消息:

The resource [URL] was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.

奇怪的是,它确实将第一个字体(Muli)应用于h1h2 标签(尽管为h2 做了一个假斜体);您可以单击错误消息中的 URL,然后在开发者控制台中会出现预加载字体的预览。

有什么线索吗? (我已经在 Windows 8.1 Pro 上的 Chrome 56 上对此进行了测试。)

<!DOCTYPE html>
<html>
<head>
    <title>Preload Font Test</title>
    <link rel="preload" href="https://fonts.gstatic.com/s/muli/v10/zscZFkjVRGyfQ_Pw-5exXPesZW2xOQ-xsNqO47m55DA.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="https://fonts.gstatic.com/s/muli/v10/YxNEAWILjDc466nftZdqXuvvDin1pK8aKteLpeZ5c0A.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="https://fonts.gstatic.com/s/opensans/v13/PRmiXeptR36kaC0GEAetxv79_ZuUxCigM2DespTnFaw.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="https://fonts.gstatic.com/s/lato/v13/tI4j516nok_GrVf4dhunkg.woff2" as="font" type="font/woff2" crossorigin>
    <style>
        h1 font-family:'Muli';font-weight:400;font-style:normal;font-size:1.5em
        h2 font-family:'Muli';font-weight:400;font-style:italic;font-size:1.5em
        h3 font-family:'Open Sans';font-weight:700;font-style:normal;font-size:1.5em
        h4 font-family:'Open Sans';font-weight:700;font-style:italic;font-size:1.5em
        h5 font-family:'Lato';font-weight:900;font-style:normal;font-size:1.5em
    </style>
</head>
<body>
    <h1>This should be in Muli regular 400 -- and it is!</h1>
    <h2>This should be in Muli Italic 400 -- but it's faux Muli Italic :(</h2>
    <h3>This should be in Open Sans Bold 700 -- but it's the default serif!</h3>
    <h4>This should be in Open Sans BoldItalic 700  -- but it's the default serif!</h4>
    <h5>This should be in Lato ExtraBold 900  -- but it's the default serif!</h5>
</body>
</html>

【问题讨论】:

如果它可以帮助其他人 - 我遇到这个问题是因为我的链接上缺少“crossorigin”属性[rel=preload] 【参考方案1】:

我已经找到了解决方案。可悲的是,W3C spec on preload links 并没有说明这一点,而且似乎有很多关于程序员发布问题的困惑,特别是关于开发人员的控制台错误消息(谷歌自己看看有多少人正在得到它并被它迷惑;这表明人们对这个非常有用的指令有多么误解)。

不能单独使用preload 链接来加载字体。它必须与@font-face 一起使用。具体来说,preload 链接必须在 @font-face 指令之前,@font-face 必须在 preload 链接之后不久出现,如果不是立即出现的话。似乎在&lt;head&gt; 部分中,preload 链接应该在您的链接中最后出现,然后@font-face 应该紧随其后,无论是在链接样式表中还是在随后的 &lt;style&gt; 部分中。

这里是原代码的修正版:

<!DOCTYPE html>
<html>
<head>
    <title>Preload Font Test</title>
    <link rel="preload" href="https://fonts.gstatic.com/s/muli/v10/zscZFkjVRGyfQ_Pw-5exXPesZW2xOQ-xsNqO47m55DA.woff2" as="font" crossorigin>
    <link rel="preload" href="https://fonts.gstatic.com/s/muli/v10/YxNEAWILjDc466nftZdqXuvvDin1pK8aKteLpeZ5c0A.woff2" as="font" crossorigin>
    <link rel="preload" href="https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="https://fonts.gstatic.com/s/opensans/v13/PRmiXeptR36kaC0GEAetxv79_ZuUxCigM2DespTnFaw.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="https://fonts.gstatic.com/s/lato/v13/lEjOv129Q3iN1tuqWOeRBgLUuEpTyoUstqEm5AMlJo4.woff2" as="font" type="font/woff2" crossorigin>
    <style>
        @font-facefont-family:'Muli';font-weight:400;font-style:normal;src:url('https://fonts.gstatic.com/s/muli/v10/BkuZCUxEYxRfSu-XBj9_CA.eot');src:url('https://fonts.gstatic.com/s/muli/v10/BkuZCUxEYxRfSu-XBj9_CA.eot?#iefix') format('embedded-opentype'),
local('Muli Regular'),
local('Muli-regular'),
url('https://fonts.gstatic.com/s/muli/v10/zscZFkjVRGyfQ_Pw-5exXPesZW2xOQ-xsNqO47m55DA.woff2') format('woff2'),
url('https://fonts.gstatic.com/s/muli/v10/minRpKQdEvXRRS8oAbAtWvesZW2xOQ-xsNqO47m55DA.woff') format('woff'),
url('https://fonts.gstatic.com/s/muli/v10/BfQP1MR3mJNaumtWa4Tizg.ttf') format('truetype'),
url('https://fonts.gstatic.com/l/font?kit=5laWPvb-IgmGJk9r92y1Hw&skey=2b55aa3f2f059b75&v=v10#Muli') format('svg');

@font-facefont-family:'Muli';font-weight:400;font-style:italic;src:url('https://fonts.gstatic.com/s/muli/v10/vurWTAYiHMPVScIey50dUQ.eot');src:url('https://fonts.gstatic.com/s/muli/v10/vurWTAYiHMPVScIey50dUQ.eot?#iefix') format('embedded-opentype'),
local('Muli Italic'),
local('Muli-italic'),
url('https://fonts.gstatic.com/s/muli/v10/YxNEAWILjDc466nftZdqXuvvDin1pK8aKteLpeZ5c0A.woff2') format('woff2'),
url('https://fonts.gstatic.com/s/muli/v10/DSOyST5zmfghBgRIogdupevvDin1pK8aKteLpeZ5c0A.woff') format('woff'),
url('https://fonts.gstatic.com/s/muli/v10/AQQ1r0_czneVCtTD9ckSEA.ttf') format('truetype'),
url('https://fonts.gstatic.com/l/font?kit=Ok1ULmeTg1kfss3jIu3xZQ&skey=f22af9a5d2e9fc47&v=v10#Muli') format('svg');

@font-facefont-family:'Open Sans';font-weight:700;font-style:normal;
src:url('https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzHZ2MAKAc2x4R1uOSeegc5U.eot');
src:url('https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzHZ2MAKAc2x4R1uOSeegc5U.eot?#iefix') format('embedded-opentype'),
local('Open Sans Bold'),
local('Open-Sans-700'),
url('https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2') format('woff2'),
url('https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzKRDOzjiPcYnFooOUGCOsRk.woff') format('woff'),
url('https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzInF5uFdDttMLvmWuJdhhgs.ttf') format('truetype'),
url('https://fonts.gstatic.com/l/font?kit=k3k702ZOKiLJc3WVjuplzFlIn5tFQcqMuf-jhyJP0ps&skey=cd9e1a36bb25a3c3&v=v13#OpenSans') format('svg');

@font-facefont-family:'Open Sans';font-weight:700;font-style:italic;src:url('https://fonts.gstatic.com/s/opensans/v13/PRmiXeptR36kaC0GEAetxrFt29aCHKT7otDW9l62Aag.eot');src:url('https://fonts.gstatic.com/s/opensans/v13/PRmiXeptR36kaC0GEAetxrFt29aCHKT7otDW9l62Aag.eot?#iefix') format('embedded-opentype'),
local('Open Sans Bold Italic'),
local('Open-Sans-700italic'),
url('https://fonts.gstatic.com/s/opensans/v13/PRmiXeptR36kaC0GEAetxv79_ZuUxCigM2DespTnFaw.woff2') format('woff2'),
url('https://fonts.gstatic.com/s/opensans/v13/PRmiXeptR36kaC0GEAetxhbnBKKEOwRKgsHDreGcocg.woff') format('woff'),
url('https://fonts.gstatic.com/s/opensans/v13/PRmiXeptR36kaC0GEAetxp_TkvowlIOtbR7ePgFOpF4.ttf') format('truetype'),
url('https://fonts.gstatic.com/l/font?kit=PRmiXeptR36kaC0GEAetxntNmQEE9wZ6UZlmiISB1pg&skey=7e5bb13249e84143&v=v13#OpenSans') format('svg');

@font-facefont-family:'Lato';font-weight:900;font-style:normal;src:url('https://fonts.gstatic.com/s/lato/v13/BjDVcwQGWPX2RAidnkd0Bw.eot');src:url('https://fonts.gstatic.com/s/lato/v13/BjDVcwQGWPX2RAidnkd0Bw.eot?#iefix') format('embedded-opentype'),
local('Lato Black'),
local('Lato-900'),
url('https://fonts.gstatic.com/s/lato/v13/lEjOv129Q3iN1tuqWOeRBgLUuEpTyoUstqEm5AMlJo4.woff2') format('woff2'),
url('https://fonts.gstatic.com/s/lato/v13/G2uphNnNqGFMHLRsO_72ngLUuEpTyoUstqEm5AMlJo4.woff') format('woff'),
url('https://fonts.gstatic.com/s/lato/v13/4cKlrioa77J2iqTqBgkRWg.ttf') format('truetype'),
url('https://fonts.gstatic.com/l/font?kit=UxBsysUD4pfKXRb0IKmcRQ&skey=d01acf708cb3b73b&v=v13#Lato') format('svg');

        h1 font-family:'Muli';font-weight:400;font-style:normal;font-size:1.5em
        h2 font-family:'Muli';font-weight:400;font-style:italic;font-size:1.5em
        h3 font-family:'Open Sans';font-weight:700;font-style:normal;font-size:1.5em
        h4 font-family:'Open Sans';font-weight:700;font-style:italic;font-size:1.5em
        h5 font-family:'Lato';font-weight:900;font-style:normal;font-size:1.5em

    </style>
</head>
<body>
    <h1>This should be in Muli regular 400 -- and it is!</h1>
    <h2>This should be in Muli Italic 400 -- and it is!</h2>
    <h3>This should be in Open Sans Bold 700 -- and it is!</h3>
    <h4>This should be in Open Sans BoldItalic 700 -- and it is!</h4>
    <h5>This should be in Lato ExtraBold 900 -- and it is!</h5>
</body>
</html>

这很有效,事实上,它确实收集了您的字体作为关键渲染路径的初始导航的一部分,这是主要的好处。 preload 目前只有 Chrome 和 Opera 支持,其他浏览器肯定会跟进。

【讨论】:

你知道字体声明是否可以在样式表中吗?即使在链接样式表中执行上述操作(以及有关未使用预加载的 Chrome 警告),我仍然会重复加载 我发现即使是相对路径也需要 crossorigin 属性,否则 chrome 会显示此警告:使用链接预加载预加载,但在窗口加载事件后的几秒钟内未使用.请确保它不是无缘无故预加载的。 这里也一样,我发现在我的情况下需要 crossorigin 属性来避免重复加载。 跨域要求让我很生气。对于那些也想知道为什么字体需要它的人,this section of the spec。另请参阅MDN section。

以上是关于使用“预加载”链接指令在 Chrome 中预加载字体的主要内容,如果未能解决你的问题,请参考以下文章

在 SpriteKit 中预加载纹理

在 Android 中预加载网页(使用 WebView?)

如何在 vue 项目中预加载图片

如何在组件样式中预加载变量

如何使用 swift 3 xcode 8 在核心数据中预加载数据库

Glide:在内存缓存中预加载图像(有或没有磁盘缓存)