-1

I don't want the render blocking of declaring a custom font using @font-face, so I've tried to copy how my google font CDN font is loaded for my custom server font, arriving at this:

    <noscript id="deferred-styles">
  <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet" type="text/css">
  <link href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext" rel="stylesheet" type="text/css">
</noscript>

But it does not work.

I've tried changing href for src="../Bluu... But that didn't work.

I've tried omitting the type, since woff2 isn't text/css.

It's important, I'm not willing to block my page load for a 35kb font file, and there's no CDN for BluuNext, so I need to find a performant way to make this work or I'll just be resigned to a beiger website.

RIGHT!

I've tried the answers below, possibly they work for other fonts but not BluuNext. Perhaps other fonts maybe come in configurations beyond bold, unlike BluuNext, so maybe that causes the issue.

It IS possible to load BluuNext font, but so far only with render blocking @font-face method, loading betwixt the tags.

Here's a minimum example including a few of the proposed solutions not working...

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:fb="http://ogp.me/ns/fb#">
  <head>
    <title>Bluu Next test</title>

<link rel="preload" as="style" href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext:bold"  />
<link rel="stylesheet" href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext" media="print" onload="this.media='all'">
<link rel="stylesheet" media="print" onload="this.media='all'" href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext:bold"  type="text/css" />
    
<noscript id="deferred-styles">
  <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext:bold" type="text/css"/>
</noscript>

<script type="text/javascript">
    // Load CSS
    var loadDeferredStyles = function() {
        var addStylesNode = document.getElementById("deferred-styles");
        var replacement = document.createElement("div");
        replacement.innerHTML = addStylesNode.textContent;
        document.body.appendChild(replacement)
        addStylesNode.parentElement.removeChild(addStylesNode);
    };
    var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
        window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); });
    else window.addEventListener('load', loadDeferredStyles);
</script>

<style>
    h2{font-family: bluuNext; font-size: 3em;}
</style>
</head><body>
<h2>Is this Bluu Next?</h2> 
  </body>
</html>

You can see some fancy javascript governing the loading of id="deferred-styles", that came at the suggestion of Google lighthouse and works well for Google's CDN fonts, not working for BluuNext so far.

Here's the link to download BluuNext, a lovely gothic, serif font. CLICK THE DOWNLOAD ARROW TOP RIGHT.

I'd love some ideas. I'd love to use this particular font, which is for some reason seemingly resistant to existing solutions.

Sam
  • 1,659
  • 4
  • 23
  • 42
  • 1
    `` only applies to clients that have JavaScript disabled entirely. – Dai Mar 09 '22 at 21:27
  • Does this answer your question? [How to load CSS Asynchronously](https://stackoverflow.com/questions/32759272/how-to-load-css-asynchronously) – Dai Mar 09 '22 at 21:27
  • “ I've tried omitting the type, since woff2 isn't text/css.” — No. It isn’t text/css. If you are copying what Google does, why are you trying to `` to a font file? Google doesn’t do that. Font files aren’t stylesheets – Quentin Mar 13 '22 at 09:37
  • Nice question ! Lighthouse force link but we need font-family style object also...! – Nikola Lukic Feb 14 '23 at 19:13

2 Answers2

0
  • The modern approach to async-style <link rel="stylesheet" /> elements is to use media="print" with onload="this.media='all'".

    • The media="print" attribute means browsers should still download the stylesheet, but won't block the page's loading.

    • The onload="this.media='all'" event-handler causes the stylesheet to become enabled when and if it does load.

    • Because browsers might still not download print stylesheets at all, you should also add an explicit <link rel="preload" /> version (for the same stylesheet) as a strong hint that the browser should download it anyway.

    • However this still depends on browsers having JavaScript enabled in order for the onload="" handler to work.

    • ...hence the need for the duplication of code in a <noscript> wrapper element.

  • Also, you really should be using root-relative (i.e. "/foo"-style) URIs in your <link href="" attributes, otherwise they wont' work if the user isn't accessing a page in your site's root.

    • I assume your BluuNext-master directory is located in your site's root.

So change your HTML to this:

<head>

    <!-- onload+media trick to defer loading these stylesheets: -->
    <link rel="preload" as="style" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"  />
    <link rel="preload" as="style" href="/BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext"  />

    <link rel="stylesheet" media="print" onload="this.media='all'" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"  type="text/css" />
    <link rel="stylesheet" media="print" onload="this.media='all'" href="/BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext"  type="text/css" />

    <!-- But if Javascript is used the <noscript> will ensure the browser will load it: -->
    <noscript>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"  type="text/css" />
        <link rel="stylesheet" href="/BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext"  type="text/css" />
    </noscript>

</head>

I do think it's silly that we need to basically repeat ourselves three times as a workaround for something that should just be a part of HTML already.

Dai
  • 141,631
  • 28
  • 261
  • 374
  • Thanks for such a complete response, unfortunately, it isn't working for me. I note that in the W3 website docs for ```@font-face``` it says ```You must add another @font-face rule containing descriptors for bold text:``` so I tried appending with ```?family=bluuNext:bold``` but that didn't work either. Instead of having the font in a font directory, I simplified it to the root, but that didn't work. Maybe the fact it's a bold font trips it up somehow. Or maybe it doesn't respect camelCase names... Thoughts welcomed. – Sam Mar 10 '22 at 12:54
  • I've tried using a direct URL rather than a relative path to include the font, that doesn't work either - GRRR. – Sam Mar 10 '22 at 14:10
0

You can not load a font directly in HTML, you need help of CSS for this. And if you open the google font link you will be able to see how it's done.

https://fonts.googleapis.com/css?family=Roboto:300,400,500

This url is a css file not a font file. Open it and you will understand how google used @font-face to load the font.

Here is the documentation from mdn: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face

Obaydur Rahman
  • 723
  • 5
  • 15
  • https://www.freecodecamp.org/news/web-fonts-in-2018-f191a48367e8/ It says you can load fonts like so: `````` I don't understand how you then apply those fonts though using CSS. It doesn't make sense to me to use a link tag to call an external stylesheet, to download fonts, it's too many steps, I'm so doubtful it's performant. – Sam Mar 22 '22 at 00:03
  • 1
    This article shows how to preload a font for better performance, `` this line of code preload or prefetch your font so when the css file needs it it can be loaded quickly. Only using this line of code the font will not be usable in your css, you must have to import it using css (@font-face) before using it. – Obaydur Rahman Mar 22 '22 at 14:19