New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: Implement font-display #358

Open
vijayaraghavanramanan opened this Issue Aug 19, 2016 · 67 comments

Comments

@vijayaraghavanramanan

vijayaraghavanramanan commented Aug 19, 2016

font-display is getting some attention, although still experimental in many browsers.

https://css-tricks.com/font-display-masses/

Chrome/Canary, Opera and Firefox have it although it is disabled by default. Hope it comes out soon.

This leaves Google Fonts to implement it. Since it should be included with the @font-face declaration, Google Fonts can allow passing of a parameter such as "&display=swap" in the URL which creates css files with a declaration:

font-display: swap;

in the css file.

Are developers of Google Fonts thinking about it?

@joaoramos

This comment has been minimized.

joaoramos commented Jun 18, 2017

Is there any progress on this topic?

@davelab6

This comment has been minimized.

Member

davelab6 commented Jun 18, 2017

@zachleat

This comment has been minimized.

zachleat commented Jun 18, 2017

It's a descriptor that goes into the @font-face block.

@davelab6

This comment has been minimized.

Member

davelab6 commented Jun 18, 2017

Aha, got it! :) Thanks!!

@thlinard

This comment has been minimized.

@zachleat

This comment has been minimized.

zachleat commented Jul 26, 2017

Now that Chrome 60 is stable, the priority for this should be bumped up! It’d be an awesome addition.

@zachleat

This comment has been minimized.

zachleat commented Aug 1, 2017

This would still be really great to have but @font-feature-values may be another option?

https://twitter.com/zachleat/status/892372316092608512
https://www.w3.org/TR/css-fonts-4/#font-display-font-feature-values

Doesn’t look like this is available anywhere yet though, so there is obviously going to be browser support mismatches between font-display and @font-feature-values so let’s keep pushing for this issue 😀

@davelab6

This comment has been minimized.

Member

davelab6 commented Aug 2, 2017

Indeed I see on the twitter more and more interest :) https://twitter.com/jeff_archibald/status/892861206939095040

@sladen

This comment has been minimized.

Contributor

sladen commented Aug 3, 2017

W3C specification:

High-level overview: new multi-browser CSS key/value pair that needs to go into each CSS snippet generated and delivered by Google Fonts:

    font-display: {auto,block,swap,fallback,optional};

When a remotely-served font is taking too long to load (or will never be loaded), this helps the browser know what to do with the textual content it is waiting to rendering. By adding font-display: swap; the browser is directed to use a local already-available system font so that the user can see/read their text quickly.

Article and jsbin demo on developers.google.com:

@webholics

This comment has been minimized.

webholics commented Sep 6, 2017

The question is whether it is save to just copy the font-face declaration which google generates for now and add the font-display on our own. At the end my question is how often a URL like https://fonts.gstatic.com/s/roboto/v16/sTdaA6j0Psb920Vjv-mrzH-_kf6ByYO6CLYdB4HQE-Y.woff2 changes?

@vijayaraghavanramanan

This comment has been minimized.

vijayaraghavanramanan commented Sep 8, 2017

@webholics

It's not just a question of how often the font URL changes.

Google fonts's css file is different for different browsers. Even the same version of Chrome in Windows and Mac will receive different css files.

So if you are suggesting that one can generate a css file simply by copy-pasting the font-face declarations into your own css file doesn't work for everyone.

So it is useful to have font-display generated in the css by the Google Fonts server itself.

@davelab6 davelab6 changed the title from Feature request: Implement font-display to Suggestion: Implement font-display Sep 22, 2017

@Androbin

This comment has been minimized.

Androbin commented Sep 23, 2017

@vijayaraghavanramanan
Just asking, why don't we use a static URL + redirect?
What are the technical considerations on this?

@vijayaraghavanramanan

This comment has been minimized.

vijayaraghavanramanan commented Sep 24, 2017

@Androbin

What do you have in mind here?

Since since the font, weights, style etc are passed in the query string in the URL, so I thought it's natural to pass "font-display" in the URL.

@Androbin

This comment has been minimized.

Androbin commented Sep 24, 2017

@vijayaraghavanramanan
Of course, I would prefer query strings as the solution.

I was just curious about why we don't redirect from some static URL to https://fonts.gstatic.com/s/roboto/v16/sTdaA6j0Psb920Vjv-mrzH-_kf6ByYO6CLYdB4HQE-Y.woff2 and the like.

I know, this becomes irrelevant with query strings. But until then, it would have been reasonable to be able to define something like:

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans Regular'), local('OpenSans-Regular'),
       url(https://fonts.gstatic.com/s/opensans/v14/<some-static-path>.woff2) format('woff2');
}

What are the technical considerations on serving different content on static paths for single font files instead of putting different paths inside https://fonts.googleapis.com/css?family=Open+Sans?

@vijayaraghavanramanan

This comment has been minimized.

vijayaraghavanramanan commented Sep 24, 2017

@Androbin

What Google Fonts does is that it creates different css files for different browsers.

The server sees the browser/version/OS and sends the right css file.

Even for a single version of Chrome in Windows/Mac OS, the font files (woff2/woff/ttf/svg/eot) are different.

Try to look at the css files in different browsers to check.

So that's why it's not appropriate to link the woff2/woff files directly.

And for that reason, the website using Google Fonts can't control "font-display" and Google may have to introduce it from their side.

@Androbin

This comment has been minimized.

Androbin commented Sep 24, 2017

@vijayaraghavanramanan
That's not my point. I understand that the file content served to different clients may be different. But just like https://fonts.googleapis.com/css?family=Open+Sans refers to different font files, it would be possible to serve the respective font files dynamically on the same static URL.

@vijayaraghavanramanan

This comment has been minimized.

vijayaraghavanramanan commented Sep 25, 2017

@Androbin

There are 847 fonts right now. Each has different weights, language, styles etc. One can even request multiple fonts like 2, 3 or maybe even 10 in the same request.

So I guess having static css files might not be optimal. Because there can be millions of different combinations.

Just guessing. Does that sound right?

@Androbin

This comment has been minimized.

Androbin commented Sep 25, 2017

@vijayaraghavanramanan
Please don't get me wrong, I don't talk about static CSS files, I do talk about static URL to address the fonts. Just like the URL https://fonts.googleapis.com/css?family=Open+Sans is non-generic and static but does serve different content for different clients, it would have been useful to be able to have static URL for the fonts like https://fonts.gstatic.com/s/opensans/v14/<some-static-path> that would then serve fonts like the one currently available via https://fonts.gstatic.com/s/roboto/v16/sTdaA6j0Psb920Vjv-mrzH-_kf6ByYO6CLYdB4HQE-Y.woff2

@vijayaraghavanramanan

This comment has been minimized.

vijayaraghavanramanan commented Sep 25, 2017

@Androbin

Apologies I didn't get the points you raised right.

Font files can be multiple. So how a single request serve multiple files?

@Androbin

This comment has been minimized.

Androbin commented Sep 25, 2017

@vijayaraghavanramanan
https://fonts.googleapis.com/css?family=Open+Sans [1]
https://fonts.gstatic.com/s/roboto/v16/sTdaA6j0Psb920Vjv-mrzH-_kf6ByYO6CLYdB4HQE-Y.woff2 [2]
https://fonts.gstatic.com/s/opensans/v14 [3]
The URL [1] dynamically generates CSS that refers to [2] and the like. What if we had [1] look something like

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans Regular'), local('OpenSans-Regular'),
       url(https://fonts.gstatic.com/s/opensans/v14) format('woff2');
}

and have [3] dynamically resolve to the font file needed (like e.g. [2]). This would move the responsibility from [1] resolving as needed to [3] resolving as needed and give developers more freedom in using CSS because the ugly URL like [2] would have been moved even more away from them.

@vijayaraghavanramanan

This comment has been minimized.

vijayaraghavanramanan commented Sep 25, 2017

@Androbin

Understand better now.

But how will you address the fact that one needs options for weights, styles and languages:

For example, I use the link for my site:

https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i&amp;subset=greek,greek-ext,latin-ext

which generates a css file with 28 font-face rules.

your [3] will just give the woff2 file for weight 400 and style normal, latin.

Nor is it desirable to request every weight and style etc. The browser looks at a page and decides which fonts to download.

So I think what Google does now is good. One quibble is that there are two servers. Ideally should have been just one - both for the css and the font files.

Another way is Typekit, where you have an account and make a kit.

@Androbin

This comment has been minimized.

Androbin commented Sep 26, 2017

@vijayaraghavanramanan
This wasn't meant as a replacement of the auto-generated CSS files, rather I mean't it might make things a bit easier in terms of e.g. the cache-ability of the CSS files as well as giving slightly more control to developers over working with the font files.

I think the query string solution is great in terms of being able to customize the font behaviour more. But in addition to this change, I might be practical to canonicalize the URL used to retrieve the respective font files.

This shouldn't be hard to implement but might de-complicate things over the long run with caching being just one example.

The real question really is: What would be used?

  • Dynamic Serving + Vary Header
  • 301 Redirect + Vary Header
  • 302 Redirect + Vary Header

Any of these options should meet come in handy in terms of e.g. cache-ability but other technical aspects might have to be considered as well.

@vijayaraghavanramanan

This comment has been minimized.

vijayaraghavanramanan commented Sep 27, 2017

I might be practical to canonicalize the URL used to retrieve the respective font files.

@Androbin

It's not easy.

The latest browsers get multiple woff2 files depending on the unicode range. So the recent versions of Chrome have separate files for latin, latin-ext, greek, greek-ext. Which the browser downloads depending on whether the page needs it or not.

Older browsers or Edge receive just one font file for a weight and a style.

So there's no one font file really.

@Androbin

This comment has been minimized.

Androbin commented Sep 27, 2017

@vijayaraghavanramanan
Yeah, I did realize that there are many font files, not one, but they could be redirected to dynamically from single URL the same way that the CSS files uses to .compile the paths.

Current: Static URL -> Dynamic CSS -> Dynamic Font Paths (-> No Redirects)
Suggestion: Static URL -> Static CSS -> Static Font Paths -> Dynamic Redirects -> Dynamic Font Paths

@vijayaraghavanramanan

This comment has been minimized.

vijayaraghavanramanan commented Sep 27, 2017

@Androbin

Don't know enough to know about redirecting to multiple files, but not the most efficient, I'd imagine.

The way unicode-range works in css font-face rules is that the browser downloads only the fonts necessary. So I don't know how redirecting to multiples can help.

@Androbin

This comment has been minimized.

Androbin commented Sep 27, 2017

@vijayaraghavanramanan
The CSS files would keep the same format but the URL it uses to point to the font files would be static. It doesn't matter if these would serve the font files directly or if they redirect to another URL. All of this can be done by looking at what files the client needs and then using the URL to figure out which unicode-range was requested.

https://fonts.googleapis.com/css?family=Open+Sans [1]
https://fonts.gstatic.com/s/opensans/v14/u-WUoqrET9fUeobQW7jkRRJtnKITppOI_IvcXXDNrsc.woff2 [2]
https://fonts.gstatic.com/s/opensans/v14/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2 [3]
https://fonts.gstatic.com/opensans/latin-ext.woff2 [4]
https://fonts.gstatic.com/opensans/latin.woff2 [5]

[2] would become [4]
[3] would become [5]
[1] would look something like

/* latin-ext */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans Regular'), local('OpenSans-Regular'), url(https://fonts.gstatic.com/opensans/latin-ext.woff2) format('woff2');
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans Regular'), local('OpenSans-Regular'), url(https://fonts.gstatic.com/opensans/latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
}

and the information, that [1] currently uses to determine the respective URL [2] and [3], could then be used to let [4] and [5] serve to font files.

The only thing that would change is that the URL pointing to the individual font files would contain just the information about the font family and the range and would then serve the font file needed using the information sent by the browser otherwise used to compile the CSS file.

@heath3

This comment has been minimized.

heath3 commented Sep 28, 2017

We currently have the ability to pass through font weights in the request query string (e.g. Roboto:400,700) which adds additional @font-face rules to the response as well as much more complex (to me anyway) functionality like the text parameter which returns a font file containing only a select number of characters. As such this does not seem like too big a task and would be a great 'quick win' for performance

Could the query string functionality not just be amended slightly so we can pass through our font-display preference in the query string too?

e.g. https://fonts.googleapis.com/css?family=Roboto|Merriweather&font-display=swap

OR

To enable different font-display values for each font requested e.g. https://fonts.googleapis.com/css?family=Roboto:font-display-swap|Merriweather:font-display-fallback.

Personally I'd be happy with either solution.

@rsheeter rsheeter self-assigned this Apr 19, 2018

@rsheeter

This comment has been minimized.

Contributor

rsheeter commented Apr 19, 2018

WRT text=, usage overall is minimal and tends to be cases where the client needs a very small set of characters that they know in advance.

WRT querystring support for setting font-display ... possible but in addition to diminished x-site caching it flies in the face of our desire to have an extremely simple API. Tell us what font and it "just works."

@addyosmani come visit, we should talk :)

@rsheeter

This comment has been minimized.

Contributor

rsheeter commented May 9, 2018

Request people who want to use font-display to star https://bugs.chromium.org/p/chromium/issues/detail?id=777846

@Ugoku

This comment has been minimized.

Ugoku commented Jul 4, 2018

It would be nice to see more green on http://caniuse.com/#feat=css-font-rendering-controls (hopefully soon)

Support is ~70% now, it would be really nice if Google Fonts supported this.

@danieldudas

This comment has been minimized.

danieldudas commented Sep 6, 2018

Google Developers suggests using Lighthouse -> Lighthouse warns about not using font-display on loading fonts -> Web page uses Google Fonts the way it's suggested on Google Fonts -> Google Fonts doesn't supports font-display -> Facepalm.

@VeeDoubleYuh

This comment has been minimized.

VeeDoubleYuh commented Sep 6, 2018

^ Why I landed here.
Also why I still frequently check this thread for updates.

Kind of funny when a service almost suggests not using another service by it's creators :P

@d-Pixie

This comment has been minimized.

d-Pixie commented Sep 14, 2018

I also landed here due to Chrome's built-in audit telling me to fix my font-display. But apparently, and highly ironically, I can't. Unless I drop Google fonts 😞

@vijayaraghavanramanan

This comment has been minimized.

vijayaraghavanramanan commented Sep 14, 2018

Facepalm.

or rather, @font-face-palm!

@kozakl

This comment has been minimized.

kozakl commented Sep 20, 2018

So strange, that google don't implemented this EASY feature yet.
The best solution, google fonts API should allow to set 'display' parameter, like this:
https://fonts.googleapis.com/css?family=Open+Sans&display=block

@addyosmani

This comment has been minimized.

addyosmani commented Sep 20, 2018

Hey folks. I lead up some of our Speed efforts in Chrome and was responsible for getting a font-display check added to Lighthouse. Please trust that we've been working diligently with the Google Fonts team on exploring (potential) support for font-display. There's unfortunately more technical work involved in adding this than just passing through a query parameter.

For example, we probably also need to support https://www.w3.org/TR/css-fonts-4/#font-display-font-feature-values in Chrome (we've started an implementation) to ensure we don't degrade Fonts high cache hit rate. To provide users (and developers) the best experience, we'll probably take a little longer to get this right, but please trust that we're exploring it.

@Zertz

This comment has been minimized.

Zertz commented Sep 23, 2018

I have implemented what seems like a pretty solid workaround using Cloudflare Workers.

https://medium.com/@pierluc/enable-font-display-on-google-fonts-with-cloudflare-workers-d7604cb30eab

Edit

I posted a follow up using a new and improved approach! Supercharge Google Fonts with Cloudflare and Service Workers

nip10 added a commit to nip10/portfolio that referenced this issue Oct 22, 2018

Remove font display
This is not supported by google fonts yet.
google/fonts#358 (comment)
@Enalmada

This comment has been minimized.

Enalmada commented Oct 31, 2018

This is my attempt to add font-display to the response with standard service worker. Unfortunately service workers are initialized after the first page load so the modification is only used in subsequent requests...and since font is now cached I think the benefit is small. Something like Cloudflare edge solution above is necessary for first time visitors to get the full benefit.

self.addEventListener("fetch", event => {
    event.respondWith(handleRequest(event))
});

async function handleRequest(event) {
    const response = await fetch(event.request);
    if (event.request.url.indexOf("https://fonts.googleapis.com/css") === 0 && response.status < 400) {
        // Assuming you have a specific cache name setup   
        const cache = await caches.open("google-fonts-stylesheets");
        const cacheResponse = await cache.match(event.request);
        if (cacheResponse) {
            return cacheResponse;
        }
        const css = await response.text();
        const patched = css.replace(/}/g, "font-display: swap; }");
        const newResponse = new Response(patched, {headers: response.headers});
        cache.put(event.request, newResponse.clone());
        return newResponse;
    }
    return response;
}
@silencesilence

This comment has been minimized.

silencesilence commented Nov 13, 2018

On this page https://developers.google.com/web/updates/2016/02/font-display
Google gives recommendations, which he does not use on https://fonts.googleapis.com/css?family=Rubik%3A300%2C400%2C500%2C700%2C900%2C300italic%2C400italic%2C500italic%2C700italic%2C900italic

BUT
https://developers.google.com/speed/pagespeed/insights/

gives me a low estimate because of their exact recommendation Implement font-display in css
this is quite confusing, they punish me for something they themselves are not doing
what do I do?

@jacksnipe24

This comment has been minimized.

jacksnipe24 commented Nov 21, 2018

any updates on this ?

@Enalmada

This comment has been minimized.

Enalmada commented Nov 21, 2018

Is there a reason why font-display: swap; isn't just made the default across all google fonts and then later on it can be made configurable for the small minority that want to customize it? It probably improves the perceived site performance for 99.9% of google font users and doesn't break anything. We have been waiting for this since 2016. It is time to make font-display: swap the default cached version for everyone.

@Zertz

This comment has been minimized.

Zertz commented Nov 21, 2018

Enabling font-display isn't not entirely transparent as it does introduce a flash of unstyled text (FOUT) which some might care about. Also, there are multiple options in addition to swap.

@Enalmada

This comment has been minimized.

Enalmada commented Nov 22, 2018

Enabling font-display: swap as the cached default would make almost every one of the billions of google font powered page views feel faster. FOUT is generally perceived as superior to FOIT and can be handled with the web font loader and font-family stack but without swap setting the only recourse for optimal performance is to use CloudFlare edge hack or self hosted font. Ultimately I hope the fonts team figures out a good way to give people access to the multiple font options but when the overwhelming majority of people using google fonts would be better off with font-display: swap it seems obvious that in a perfect world this ticket would be about giving edge case users the ability to customize away from swap rather than the sad state of swap not being the default that we are in now. Make swap the default to improve the internet for almost everyone and then make this ticket about how to enable an option that deviates from best practice.
https://www.zachleat.com/web/fout-vs-foit/

@pauloddr

This comment has been minimized.

pauloddr commented Nov 22, 2018

FOUT can be pretty bad with Material Icons, which is served by GoogleFonts. Unstyled text for a material icon is a full word (or words), and depending on the size of the icon, it can be quite disruptive to the user. Other than that, FOUT/swap does seem more appropriate for non-icon fonts. I do have the feeling though that Material Icons might be one of the most served fonts, since there's a large amount of SPA/PWA sites out there, and any website wanting a free icon font would also request it without the need of self-hosting.

If requesting for a custom font-display via query parameter is a no-go, I'd be okay with making an exception for Material Icons (to keep it FOIT) and make FOUT the default for the rest.

@gnanet

This comment has been minimized.

gnanet commented Nov 25, 2018

On this page https://developers.google.com/web/updates/2016/02/font-display
Google gives recommendations, which he does not use on https://fonts.googleapis.com/css?family=Rubik%3A300%2C400%2C500%2C700%2C900%2C300italic%2C400italic%2C500italic%2C700italic%2C900italic

BUT
https://developers.google.com/speed/pagespeed/insights/

gives me a low estimate because of their exact recommendation Implement font-display in css
this is quite confusing, they punish me for something they themselves are not doing
what do I do?

Even more (un)funny fact:

  1. the lighthouse test running online on pagespeed insights does not detect font-display while a lighthouse audit within Chrome 70 properly detecting it.
  2. Web Fundamentals > Web Font Optimization describes preload, but completely missing the required tags: crossorigin and type. The best reading on the font loading topic is Zach Leatherman's guide
@wtct

This comment has been minimized.

wtct commented Dec 5, 2018

It's a real huge pity that PageSpeed Insights recommends using font-display, but Google Fonts doesn't support it. The same with Typekit Web Fonts Loader.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment