Load Google Font with <link> asynchronously or deferred without Font Face Observer
Asked Answered
F

7

50

I want to use the Google Font "Noto Serif" for my website. My problem is that when I am testing it with Google PageSpeed Insights, it says everything is perfect except for one thing:

<link href="https://fonts.googleapis.com/css?family=Noto+Serif" rel="stylesheet">

Your page has 1 blocking CSS resources. This causes a delay in rendering your page. None of the above-the-fold content on your page could be rendered without waiting for the following resources to load. Try to defer or asynchronously load blocking resources, or inline the critical portions of those resources directly in the HTML.

I am aware of a bad solution for this. It's to link the font using <script> at the bottom of the HTML file. The problem with that solution is it causes a Flash of Unstyled Text every time you click on something in my website.

I am using jekyll hosted with GitHub Pages, so I don't think I can install Font Face Observer :(

Flagrant answered 16/11, 2016 at 5:13 Comment(1)
Please use localfont.com for all obvious reasons...Chrysarobin
D
-5

Here ya go, include this in the body tag and not the head tag

   <link href="https://fonts.googleapis.com/css?family=Noto+Serif" rel="stylesheet" lazyload>

Updated 2020

 <link rel="preload" as="style" href="https://yourcss.css" onload="this.rel='stylesheet'" />
Dew answered 16/11, 2016 at 5:16 Comment(4)
@StuffedMarshmallow The "lazyload" attribute comes from an abandoned W3C proposal, and it was only implemented by Internet Explorer and Edge. I would not recommend using it on a public website. To asynchronously load Google Fonts in all browsers, you should use their JavaScript Web Font Loader.Therapeutics
To proof the comment of soren please check caniuse.com/#feat=lazyload and you'll see he ist right. So do not use this solution in your production environment.Davide
as of October 2020 @Pavlo Razumovskyi has the correct answer, please use that, as this is what I now use as well.Dew
we can do it on head ?Plough
I
23

You can load the web fonts asynchronously with this script:

<script>
   WebFontConfig = {
      typekit: { id: 'xxxxxx' }
   };

   (function(d) {
      var wf = d.createElement('script'), s = d.scripts[0];
      wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';
      wf.async = true;
      s.parentNode.insertBefore(wf, s);
   })(document);
</script>

You'll need this library, it's pretty easy to implement. I've learn this from a course I took recently, Responsive Web Design Fundamentals, if you're interested you can check it out here.

Indore answered 25/3, 2018 at 21:20 Comment(4)
The library (webfontloader) seems to be no longer maintained. Also some peeople have issues with it working in IE and edge. I have doubts about using it.Wolfy
Thanks for the heads up and the edit, I've haven't used it in about a year.Indore
Keep in mind, that this will prevent font loading when JavaScript is disabled.Freethinker
@Freethinker Agree. Better to put a noscript tag with the original link tag inside. That would make the font load like normal when JS is disabled.Theine
M
21

Based on this strategy to preload stylesheets:

<link rel="preload" 
      href="https://fonts..."
      as="style"
      onload="this.onload=null; this.rel='stylesheet'; document.body.classList.add('fontLoaded')">
body {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

body.fontLoaded {
  font-family: 'GOOGLE FONT', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
Moonseed answered 26/12, 2019 at 0:37 Comment(3)
Do you think it's affect the swap display type that google fonts API give?. Google Fonts give this URL for Roboto font https://fonts.googleapis.com/css2?family=Roboto:wght@400&display=swapEvertor
@pavlo keep in mind that this is not yet fully supported and the styles won't load everywhere: caniuse.com/#search=preloadDoth
Check out walterebert.com/playground/css/asyncRapport
C
5

Add two attributes to your code. One is rel="preload" and the other is as="style". The final code would look like the below:

<link href="https://fonts.googleapis.com/css?family=Noto+Serif" rel="stylesheet" rel="preload" as="style">
Conney answered 20/10, 2020 at 6:9 Comment(1)
As far as I can tell, this doesn't work. If you have duplicate rel attributes, then the last one "overrides" the preceding ones, so rel="preload" is ignored. You need to only have the rel="preload" and then switch it to rel="stylesheet" after it's loaded, like this answer that I just added.Londalondon
L
2

Very simple approach:

<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">

Just replace styles.css with your font URL. It loads the font, and then once it finishes (onload) it "enables" it by switching the rel property to stylesheet.

More details here.

Londalondon answered 29/5, 2022 at 9:3 Comment(0)
I
0

Only add block tag

 https://fonts.googleapis.com/css?family=Noto+Serif&display=block

Ref : Controlling Font

Invective answered 7/8, 2019 at 23:20 Comment(1)
From the link you provided: "block gives the font face a short block period (3s is recommended in most cases) and an infinite swap period. In other words, the browser draws "invisible" text at first if the font is not loaded, but swaps the font face in as soon as it loads". Which means it will lead to an inevitable FOIT.Freethinker
B
0

Has any one tried this solution?

<!-- other <head> stuff -->

<!-- connect to domain of font files -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- optionally increase loading priority -->
<link rel="preload" as="style" href="(font CSS URL here)">

<!-- async CSS -->
<link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="(font CSS URL here)">

<!-- no-JS fallback -->
<noscript>
    <link rel="stylesheet" href="(font CSS URL here)">
</noscript>

</head>
Bixby answered 14/1, 2021 at 9:35 Comment(0)
D
-5

Here ya go, include this in the body tag and not the head tag

   <link href="https://fonts.googleapis.com/css?family=Noto+Serif" rel="stylesheet" lazyload>

Updated 2020

 <link rel="preload" as="style" href="https://yourcss.css" onload="this.rel='stylesheet'" />
Dew answered 16/11, 2016 at 5:16 Comment(4)
@StuffedMarshmallow The "lazyload" attribute comes from an abandoned W3C proposal, and it was only implemented by Internet Explorer and Edge. I would not recommend using it on a public website. To asynchronously load Google Fonts in all browsers, you should use their JavaScript Web Font Loader.Therapeutics
To proof the comment of soren please check caniuse.com/#feat=lazyload and you'll see he ist right. So do not use this solution in your production environment.Davide
as of October 2020 @Pavlo Razumovskyi has the correct answer, please use that, as this is what I now use as well.Dew
we can do it on head ?Plough

© 2022 - 2024 — McMap. All rights reserved.