4

So recently, we have been looking into optimizing our website for the new "Core web vitals", and has pinpointed the issues to be related to flexbox row (resolved), which resulted in bad CLS score for Desktop, and on Mobile it appears to be Google Web Fonts destroying the CLS score.

When we add this little code all is looking good. CLS score is 0. When we use Google Web Font, the score is 0.326 (For mobile only, desktop seems fine).

<style>
*:not(i){
    font-family: sans-serif!important;
}
</style>

Here is the way that we are using Google Fonts.

<link rel="preconnect" href="https://fonts.gstatic.com/">
<link rel="stylesheet" rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&family=Source+Sans+Pro:wght@400;900&display=swap">

Why do we have rel="stylesheet" and rel="preload"? The latter is not yet supported on browsers such as Firefox, we learned, where previously the fonts would not load completely, this was fixed when we added stylesheet as well.

What have we tried?

We have tried changing the &display=swap value to things such as block,fallback,optional as recommended in other articles, none of these affected the CLS score, though it seemed that there was no FOUT (tested with throttled "Fast 3G".).

We also tried self-hosting all the fonts, that didn't really work either.

Still, we do believe this is related to the fonts, as when we apply the CSS above, the CLS score is 0. Which is what we are looking for, but we still would like the webfonts. Also, when we change the &display=swap value, we get another "warning" in Lighthouse, recommending to use the swap for better user experience, but this is what causes the CLS problem... Any ideas?

Here are the results, with just this simple change (CSS) as mentioned above.

Score: 94 (Mobile) - 93 (Desktop) = Nice..!

enter image description here

And this is without the CSS above, and Google webfonts.

Score: 69 (Mobile) - 91 (Desktop) = Mobile could be better.. All good on Desktop.

enter image description here

Anders
  • 513
  • 2
  • 10
  • 32
  • You may find [this answer I gave useful (the "Solutions" section.)](https://stackoverflow.com/a/64360761/2702894) Having battled with this myself multiple times this is what we landed on, but obviously it isn't always an option if your font is not close in style to a web safe font. – GrahamTheDev Oct 17 '20 at 09:55
  • @GrahamRitchie It does indeed seem like there are some tradeoffs to consider here. Personally I prefer the display=swap as Google suggests too, user-experience-wise. I will wait a bit, and see if Google comes out with clearer guidelines to improve CLS and layout shifts, there are tons of websites using Google webfonts as well. – Anders Oct 17 '20 at 10:26
  • 1
    From a user experience perspective speed > which font you use. People generally don't care as much as we do about the font. As you are using open-sans just a normal sans-serif font would work fine. But obviously the choice is yours, just suggesting the best fix (but our focus is speed as it affects conversion rates so greatly). Google has official guidance [here](https://web.dev/preload-optional-fonts/) but it doesn't actually work in most real world scenarios as timeout is too short. Another option you have is to have a white overlay while the font loads in, which yet again is not ideal. – GrahamTheDev Oct 17 '20 at 10:41
  • 1
    The additional benefit of doing it this way is that you don't have to wait for ~300kb of fonts to download to render the page, this gets your FCP & LCP numbers back to great numbers. The only other experiment we ran (didnt quite get it right) was loading a massively optimised variable font (just A-Za-z0-9 & core punctuation) inline using a data URI. It only added 20kb to page weight & loaded instantly (as it was inlined in the HTML) but it still had jank when we swapped the full version in. Might be something I revisit soon as we were close to a working solution. If I do I will let you know. – GrahamTheDev Oct 17 '20 at 10:48
  • @GrahamRitchie I agree with you. We will continue to do some testing as well, will let you know if anything improves. Best of luck with your projects. – Anders Oct 18 '20 at 08:54

1 Answers1

2

Here are two solutions I know to deal with this issue:

Style the fallback fonts to match the web font and use the [CSS Font Loading API] to change classes when the webfont loads.

See here for an example of using the Font Loading API to launch a callback when a certain font loads. You can use a tool like this one to match up the fallback font to the web font.

Use chrome's @font-face descriptors override on the fallback font to match the webfont

Font descriptors override just arrived in chrome 87, they let you perform the same functionality as option 1, but without the need for separate classes and JavaScript, you just target a specific font-family inside of a @font-face. The downside is that this is only available in chrome 87 at the time of writing this.

oreoorbitz
  • 109
  • 1
  • 4