Support for automatic `link rel="preload"` elements for fonts
codeflorist opened this issue · comments
SEO- and performance-wise it makes sense to add a <link rel="preload"
head-tag for the fonts used by the site.
Since font-file-names and -locations can change (e.g. because of version/hashes), it would be great, if nuxt/fonts
does that automatically. Ideally it could be enabled by family, like e.g.:
{ name: 'My Font Family', provider: 'google', preload: true },
Adding preload by default can result in over-download fonts in a blocking way as a font may not be used on the page.
This shouldn't be needed if the font face rule + font-family are inlined in the HTML.
Do you have an example where preloading the fonts with Nuxt Fonts makes a positive difference in performance? Would you suggest that setting preload: true
would result in just preloading woff2 files, for example? For all weights?
I guess the optimal solution would be an automatic one, that dynamically creates the preload-tags for fonts, that are actually used on the current page. They must of course be in the initial HTML - so pre-generated on server.
Otherwise i would definitely make it optional - at least by family, even better by weight/style-variant.
But i guess it's safe to say, that in 95% of all projects you have 1 or 2 fonts pretty much used on every page (a normal body font and sometimes an additional display font for headers. )
Regarding the font-format, i'd only use woff2 (or make it configurable), as that's the de-facto standard now (can i use reports 97,33% support worldwide). And according to this article...
specifying preloading for multiple types of the same resource is discouraged. Instead, the best practice is to specify preloading only for the type the majority of your users are likely to actually use.
As for the actual performance advantage, i don't have any numbers. But it is recommended by google - see here). It reduces flash of unstyled text (FOUT)
- a relevant metric for Google's Page Speed score (specifically FCP
and LCP
). Thus it should be also relevant for SEO. Here is what Page Speed has to say about it:
Consider using
<link rel=preload>
to prioritise fetching resources that are currently requested later in page load. Learn how to preload key requests
This shouldn't be needed if the font face rule + font-family are inlined in the HTML.
I haven't heard that before, but i guess it could be the case. But maybe preload has additional advantages, like being parsed first or getting handled with priority by the browser. But as Google recommends it, i'm sure it has at least advantages for their speed (and thus SEO) metric.
I've released v0.2.0 with support for font preloading (you'll need to enable with fonts.experimental.addPreloadLinks
). I'd appreciate any feedback or performance measurements you or others are able to do. 🙏
Hey Daniel,
Many thanks for the fast implementation!
Unfortunately i cannot get this to work. I have this in my nuxt config:
fonts: {
experimental: {
addPreloadLinks: true
}
},
But no preload-link is showing up either in dev
, build
or generate
.
@codeflorist Could you provide a reproduction? 🙏
I'm facing a similar issue using UnoCSS and this plugin (I guess).
unocss.config.ts
presetWebFonts({
//provider: 'google',
fonts: {
sans: "Roboto",
serif: "Rubik",
mono: ["Fira Code", "Fira Mono:400,700"]
}
})
nuxt.config.ts
fonts: {
experimental: {
addPreloadLinks: true
}
}
And when I visit the site, I see fonts getting downloaded from static
Maybe I got addPreloadLinks
wrong. Is something else needed to store fonts locally during build instead?
With this module you do not need the unocss web font preset.
Good to know, and I also was not on the latest version
please fix addPreloadLinks, the preload link tag not appears!
@agracia-foticos Please open an issue with a reproduction 🙏
@danielroe https://stackblitz.com/edit/nuxt-starter-et4gzh here you are
There isn't any link rel="preload" with Signika hashed name Font
@agracia-foticos Preload links are not inserted in dev mode. (improved docs just now here)
@agracia-foticos Preload links are not inserted in dev mode. (improved docs just now here)
Compiling in PROdution mode i dont see <link rel="preload" with each font
@agracia-foticos Cloning your reproduction and running build, this was the output:
...
<style>
@font-face{font-family:Signika;src:local("Signika Variable"),url(/_fonts/vEFO2_JTCgwQ5ejvMV0Ox_Kg1UwJ0tKfX6bOjM7-f7e0Mls-xQWzOkeLSd.woff2) format(woff2);font-display:swap;unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;font-weight:300 700;font-style:normal}
/** removed more font faces here */
#element{font-family:Signika, "Signika Fallback: Arial"}</style>
<link rel="stylesheet" href="/_nuxt/entry.DFgiMwVT.css">
<link rel="modulepreload" as="script" crossorigin href="/_nuxt/CYhS_UQ5.js">
<link rel="preload" as="font" crossorigin href="/_fonts/vEFO2_JTCgwQ5ejvMV0Ox_Kg1UwJ0tKfX6bOjM7-f7e0Mls-xQWzOkeLSd.woff2">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/rEEB8dd5.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/7Il5epJC.js">
...
If you want to continue to discuss, please open a new issue. 🙏 This issue is to track automatic support for preload links, which is a future enhancement.
It seems the preload-tag is not generated for fonts, that are defined in tailwind.config.ts
.
I define my font in tailwind-config like this:
theme: {
fontFamily: {
body: ['"Felipa"', ...defaultTheme.fontFamily.sans],
},
},
And then set this css inside assets/css/tailwind.css
:
html {
@apply font-body;
}
Basically, nuxt/fonts
is correctly picking up and downloading this font with everything seemingly working correctly, but it does not create the preload-tag.
Here is a stackblitz:
https://stackblitz.com/edit/nuxt-starter-xrzkqs?file=app.vue
If you add this to app.vue
, the preload-tag gets added correctly:
<style scoped>
div {
font-family: Felipa, serif;
}
</style>