FortAwesome / Font-Awesome

The iconic SVG, font, and CSS toolkit
https://fontawesome.com
Other
73.63k stars 12.19k forks source link

Lighthouse Issue with Font Performance for font-display #14387

Closed gyto closed 4 years ago

gyto commented 5 years ago

Currently, if you try to use a Lighthouse tool in the Chrome you would find that "Text is invisible while web fonts are loading" in which we need to "Leverage the font-display CSS feature to ensure text is user-visible"

In this case, it means that @font-face should load with font-display property. In case of the icons, it should be load in font-display: block which helps the font face a short block period.

In the main time, I am using font awesome as a package which I am importing it to the project via SCSS.

Is this something that can be added to the @font-face?

Reference:

tagliala commented 5 years ago

Hi!

Thanks for being part of the Font Awesome Community.

Interesting!

Have you an 1-vs-1 comparison? Do you know if there are any breaking changes in including this property on the supported browsers?

kiler129 commented 5 years ago

@tagliala There's no side effects for supported browsers - the declaration is ignored and FA behaves like it wasn't ever set. font-display is really just a hint for rendering engine which may be even ignored by browsers depending on e.g. power saving settings.

yolofy commented 5 years ago

+1

gyto commented 5 years ago

@tagliala per @kiler129 it is not about support browsers, this is Lighthouse report that I getting recently and fonts are really something that I would like to fix on my project with font-display: auto;

tagliala commented 5 years ago

Thanks for the heads-up

@robmadole could you please take a look?

jorgehjr84 commented 5 years ago

This is also something I would be interested in as well. It should be a simple fix in the _path.scss file(in version 4.7. Not sure about the current version)

@font-face {
  font-family: 'FontAwesome';
  font-display: swap;
  src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
  src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
    url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
    url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
    url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
    url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
//  src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
  font-weight: normal;
  font-style: normal;
}

You would just add font-display below the font family line

tagliala commented 5 years ago

Isn't font-display supposed to be block?

Also, just because it is one css it doesn't mean that it is a simple fix πŸ˜…

It should always be tested against all browsers supported by Font Awesome and prepare for something we didn't think about

yolofy commented 5 years ago

Definitely not block, swap is recommended as the best performing option.

Check out this guides: https://css-tricks.com/font-display-masses/ https://css-tricks.com/almanac/properties/f/font-display/

yolofy commented 5 years ago

Here is a cool demo of the differences between the various options: https://font-display.glitch.me/#demo

tagliala commented 5 years ago

swap: Fallback text is immediately rendered in the next available system typeface in the font stack until the custom font loads, in which case the new typeface will be swapped in. This is what we want for stuff like body copy, where we want users to be able to read content immediately.

what would be a system replacement for Font Awesome? Any local installed version? πŸ€”

yolofy commented 5 years ago

https://css-tricks.com/snippets/css/using-font-face/#article-header-id-17 What About Icon Fonts? It's true, @font-face can load a font file full of icons that can be used for an icon system. However, I think you're far better off using SVG as an icon system. Here's a comparison of the two methods.

https://css-tricks.com/icon-fonts-vs-svg/

jorgehjr84 commented 5 years ago

@tagliala I'm aware of development processes and was not suggesting that you should deploy a 1 line CSS fix without doing your due diligence of testing across all browsers, etc. Hence why I said It should be a simple fix. Thanks for looking into it

gyto commented 5 years ago

swap: Fallback text is immediately rendered in the next available system typeface in the font stack until the custom font loads, in which case the new typeface will be swapped in. This is what we want for stuff like body copy, where we want users to be able to read content immediately.

what would be a system replacement for Font Awesome? Any local installed version? πŸ€”

I agree with @tagliala. At this point, it should be font-display: auto or font-display: block

yolofy commented 5 years ago

Would it be possible to make this a setting in _variables.scss?

robmadole commented 5 years ago

I'm going to add it to _variables with a value of auto so it can be overridden. I would like to be very cautious about changing this in a major version (it's something that we might consider in version 6 but would not change drastically in 5). Also I'm not convinced that font-display: block; is a good idea for FA πŸ˜‰.

gyto commented 5 years ago

@robmadole so does it mean that you will implement variable in the nearest release version?

tagliala commented 5 years ago

https://github.com/FortAwesome/Font-Awesome/blob/master/scss/_variables.scss#L6 https://github.com/FortAwesome/Font-Awesome/blob/master/scss/solid.scss#L11

Feel free to set the variable as you wish

kiler129 commented 5 years ago

Thank you all!

gyto commented 5 years ago

Thank you, @robmadole and @tagliala

rilwis commented 5 years ago

@tagliala Can it be swap by default? We use FontAwesome CDN and can't change it.

stave15 commented 5 years ago

This is my site https://www.fileour.com/ I will try to fix the font problem. But it not works fine. I am very sad.

kiler129 commented 5 years ago

You cannot mark it swap by default - this will cause random characters to appear (or in the best case squares). This is a very bad UX.

See the explanation from Google: swap gives the font face a zero second block period and an infinite swap period. This means the browser draws text immediately with a fallback if the font face isn’t loaded, but swaps the font face in as soon as it loads.

This behavior is desired for small blocks of text (e.g. headings). For big chunks of texts you should use fallback for big blocks (e.g. article contents). The block setting gives the user no icons on load and loads them as soon as possible, which is better than broken icons blinking into proper icons.

On Mar 20, 2019, at 9:03 PM, Tran Ngoc Tuan Anh notifications@github.com wrote:

@tagliala Can it be swap by default? We use FontAwesome CDN and can't change it.

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

stave15 commented 5 years ago

Thank you. I will try this.

rilwis commented 5 years ago

@kiler129 Thanks! That's very helpful.

innostar commented 5 years ago

Thanks 😊 alot https://www.tugadar.com

garygreen commented 5 years ago

You cannot mark it swap by default - this will cause random characters to appear (or in the best case squares). This is a very bad UX.

It's worth noting that there is a new experimental technology FontFace that allows you to dynamically load the font which returns promise for when the font is loaded. With this API you can do something like this:

  1. Setup your css to hide fontawesome fonts and then show them once the font is loaded:
.fa {
   display: none;
}

body.fontawesome-loaded .fa {
    display: initial; /* may not work in IE, use inline-block / block instead */
}
  1. Dynamically load the font with FontFace:
// Use whatever url here.
var font = new FontFace('FontAwesome', 'url(/dist/css/fonts/fontawesome-webfont-78afaf295226344f213f8739237587ed.woff2)');
font.load().then(function(font) {
   document.fonts.add(font);
   document.body.classList.add('fontawesome-loaded');
});

Make sure you don't define a @font-face block for fontawesome as it's not needed with this method and may cause blocking of rendering if you do.

FontFace is pretty well support in most browsers now. I'd imagine there's a polyfill for it out there as well.

image

MastaBaba commented 5 years ago

How to make this work when using either the free font awesome kit, or the FontAwesome Wordpress plugin? Using the Wordpress plugin, PageSpeed tells me "Ensure text remains visible during webfont load", referencing three FontAwesome files.

MastaBaba commented 5 years ago

@garygreen: That's neat. But, for me, using this approach does load the file, but the font is not displayed.

rosemusic commented 5 years ago

i have same issue in my site https://www.rosemusics.com

tagliala commented 5 years ago

Hi @rosemusic,

the best option for icon fonts is the block display, otherwise you will see squares while loading. Ref: https://github.com/FortAwesome/Font-Awesome/issues/14387#issuecomment-475097395 and we don't want that

If you are interested in improving your website's performance, my advise is to use svg files directly or to use a custom version of the SVG framework (webpack/rollup with tree shaking) with async loading of the javascript asset

Ref:

rosemusic commented 5 years ago

Hi @rosemusic,

the best option for icon fonts is the block display, otherwise you will see squares while loading. Ref: #14387 (comment) and we don't want that

If you are interested in improving your website's performance, my advise is to use svg files directly or to use a custom version of the SVG framework (webpack/rollup with tree shaking) with async loading of the javascript asset

Ref:

* https://fontawesome.com/how-to-use/on-the-web/setup/using-package-managers

* https://fontawesome.com/how-to-use/with-the-api/other/tree-shaking

thanks so much.

andreacfromtheapp commented 4 years ago

hi,

I'm having the same OP issue with lighthouse and I don't know how to solve it.

I don't host fonts nor scripts locally anymore because it's a small static site hosted on gitlab pages and it had massive performance issues when I did. hence my switch to cdn for FA (cdnjs), gfonts, jquery and leaflet maps.

I see that this issue has been resolved and closed but I cannot find a way to use &display=swap in the cdn url as google fonts offer. is that possible with FA/cdnjs? how? any advice would be highly appreciated.

thanks

robmadole commented 4 years ago

@gacallea you don't want to use swap. block is the appropriate setting for an icon font.

andreacfromtheapp commented 4 years ago

@robmadole thanks for your quick reply. how do I do that? is it the default?

robmadole commented 4 years ago

It's the default. But Lighthouse is going to ding you for it. I don't think there is anything that can be done about that.

Stanzilla commented 4 years ago

I filed https://github.com/GoogleChrome/lighthouse/issues/10127 for that.

patrickhulce commented 4 years ago

πŸ‘‹ Lighthouse maintainer here, Lighthouse will not ding you for using block. If the Font Awesome CDN were to explicitly declare the font-display as block by default that seems like a win-win for everyone involved.

The intention of that audit is to explicitly opt-in or opt-out of font blocking, not to force icon fonts to render gibberish characters; no one wants that :)

Stanzilla commented 4 years ago

@tagliala Please re-open :)

tagliala commented 4 years ago

@Stanzilla thanks for the heads-up, I've missed @patrickhlauke 's comment (sorry!)

Perfect, we can set block as a default value one more time (we switched from block to auto)

About FA 4's CDN link, it is in EOL, and it is not hosted by us

/cc @robmadole

tagliala commented 4 years ago

Sorry, I'm going to close this in favour of #16077