最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to avoid page jump and FOUT during font loading and page loading - Stack Overflow

programmeradmin2浏览0评论

I am developing a website and I can't host the font. So it has to be loaded from an external resource. However, it loads slowly and because the font is not a standard font, it causes massive page jump on loading. The browser default font always loads first and when the font changes everything moves around and the entire scroll height of the page changes. And it's a big problem because one of the forms on the page shifts right at the point where you'd be starting to select a field and you end up selecting the wrong one when it jumps.

I have tried using font pre-loading just to find out that there is a massive lack of browser support. And even with testing on google chrome which is supposed to support it, it seems to fail and resort to the browser default font once in a while. ( link rel preload...)

Currently, I'm using a messy javascript solution that basically hides the page until the font loads and then uses a timeout to allow the browser time to render with the new font before making the page visible again. And then it uses another timeout that's a bit longer in case the font doesn't load at all to show the page as a backup.

It feels really unprofessional. I feel like it's causing an additional delay on the users end which shouldn't be necessary. There has to be a better way to go about this but I'm not finding one. I can't set a fixed height for the elements because some of the content and questions in the forms is user generated. I'm listing the terrible inline code which I'm currently using.

document.body.style.visibility="hidden";
//the link element that loads the font currently has an id
var font=document.getElementById('font');
font.onload=function(){
    var timeout=self.setTimeout(function({
    document.body.style.visibility="visible";
},100);
}
var fallback=self.setTimeout(function(){
document.body.style.visibility="visible";
},1000);

I don't mind the results I'm getting with my current solution. But I feel like there definitely has to be a better way of going about this?

I am developing a website and I can't host the font. So it has to be loaded from an external resource. However, it loads slowly and because the font is not a standard font, it causes massive page jump on loading. The browser default font always loads first and when the font changes everything moves around and the entire scroll height of the page changes. And it's a big problem because one of the forms on the page shifts right at the point where you'd be starting to select a field and you end up selecting the wrong one when it jumps.

I have tried using font pre-loading just to find out that there is a massive lack of browser support. And even with testing on google chrome which is supposed to support it, it seems to fail and resort to the browser default font once in a while. ( link rel preload...)

Currently, I'm using a messy javascript solution that basically hides the page until the font loads and then uses a timeout to allow the browser time to render with the new font before making the page visible again. And then it uses another timeout that's a bit longer in case the font doesn't load at all to show the page as a backup.

It feels really unprofessional. I feel like it's causing an additional delay on the users end which shouldn't be necessary. There has to be a better way to go about this but I'm not finding one. I can't set a fixed height for the elements because some of the content and questions in the forms is user generated. I'm listing the terrible inline code which I'm currently using.

document.body.style.visibility="hidden";
//the link element that loads the font currently has an id
var font=document.getElementById('font');
font.onload=function(){
    var timeout=self.setTimeout(function({
    document.body.style.visibility="visible";
},100);
}
var fallback=self.setTimeout(function(){
document.body.style.visibility="visible";
},1000);

I don't mind the results I'm getting with my current solution. But I feel like there definitely has to be a better way of going about this?

Share Improve this question asked Aug 7, 2019 at 17:14 TheTylerTheTyler 311 silver badge2 bronze badges 4
  • I would agree with your assessment that the delay on the client side is unideal and unnecessary. Studies have shown that every second the user has to wait before meaningful rendering increases the bounce rate significantly. Have you looked at potentially narrowing the character set loaded with unicode-range? You can read about this and other strategies here and here. – IronFlare Commented Aug 7, 2019 at 17:24
  • Just looked at the links. Totally valid, it would load faster, especially since, realistically I'd just be using A-Z and 1-9 etc so a fairly limited character range. Thank you English language hehe. – TheTyler Commented Aug 7, 2019 at 19:00
  • Oh yeah, any idea on how to avoid the FOUT - flash of unformatted text? Because it always seems to load the default font before loading the custom one. – TheTyler Commented Aug 7, 2019 at 19:02
  • At the end of the day, if you're stuck with loading the font from an external provider, your hands are likely somewhat tied. I've created an answer with more detail about potential promise solutions. – IronFlare Commented Aug 7, 2019 at 22:12
Add a ment  | 

3 Answers 3

Reset to default 4

If you are using Google fonts make sure you don't have the &display=swap query param set.

<link href="https://fonts.googleapis./css2?family=Montserrat:wght@100;200;300;400;500;700;900&display=swap" rel="stylesheet">

This instructs the browser to do a font jump in every case. Jumping fonts is not good, especially above the fold. Remove the &display=swap and the jump will stop.

I would agree with your assessment that the delay on the client side is unideal and unnecessary. Case studies by Google and the BBC have found that every second of load time can increase the bounce rate (the number of people who leave the site after visiting just one page) by as much as 10-20%.

One strategy you could use to reduce load time is narrowing the character set you load. If you're hosting the fonts yourself, segmenting the font and using a unicode-range value in your @font-face definition would be the best way to acplish this. Some providers like Google Fonts allow you to do this with query string parameters, as well. This can significantly reduce the number of unused, unneeded glyphs (e.g., foreign and special characters) that the client has to load.

As for reducing FOUT, one thing you could try is downloading the roman (regular) style to your machine, encoding it as base-64, and then embedding it directly into your page styling, e.g.,

@font-face {
    font-family: MyFontName;
    src: url('data:application/x-font-woff;charset=utf-8;base64, <font data> ') format('woff');
    font-weight: normal;
    font-style: normal;
}

Because the normal font style is directly integrated into your HTML/CSS contents, its load time is insignificant. The great part about this is that when browsers receive only a regular style, they automatically generate their own bold and italic versions. You can take advantage of this behavior and use it as a stand-in for your proper styles until they load.

Also, if you're not doing so already, take a look at different web font formats like WOFF2, and pression methods like Brotli (which WOFF2 uses).

Here are a couple of resources that cover these and other methods in detail:

  • A Comprehensive Guide to Font Loading Strategies

  • FOUT, FOIT, FOFT

I added the property font-display: block; and that worked for me

@font-face {
    font-family: 'Quisas';
    font-display: block;
    src: url('./fonts/quisas/Quisas.otf') format('opentype');
}
发布评论

评论列表(0)

  1. 暂无评论