ampproject / amphtml

The AMP web component framework.
https://amp.dev
Apache License 2.0
14.89k stars 3.89k forks source link

Automatically add @font-face for custom whitelisted Google fonts via AMP CDN. #23151

Open anuragphadke opened 5 years ago

anuragphadke commented 5 years ago

Google Fonts and certain whitelisted fonts are extremely popular and widely used. There are two main ways to load them:

  1. via css <link href="https://fonts.googleapis.com/css?family=Muli|Open+Sans:400,700&amp;display=swap" rel="stylesheet"/>

  2. via @font-face

The CSS option is render blocking and causes slowness. The @font-face option is the preferred and super-fast. However, using @font-face option involves adding the src which becomes cumbersome when you are using multitude of fonts.

Proposal: When AMP pages are hosted on AMP CDN,

  1. provide a way to automatically parse the rel="stylesheet".
  2. discover the white-listed fonts that are being used.
  3. inject the fonts directly from the reference stylesheet as @font-face.
  4. Don't count the @font-face included by this approach towards the 50KB CSS limit.

Future:

  1. Extend the above method towards all fonts, whitelisted and otherwise.

Advantage: Font's are render blocking and this approach can speed up things while maintaining UI/UX consistency and with less code.

Update: According to https://github.com/ampproject/amphtml/issues/11249, fonts aren't render blocking, however, lightspeed and PSI both suggest to use @font-face instead of the above link-href approach.

Assuming Lightspeed/PSI is incorrect, should we open a ticket on their side?

cvializ commented 5 years ago

/cc @ampproject/wg-caching @ampproject/wg-performance

Gregable commented 5 years ago

Sorry for the delay in responding. I think this is a good suggestion. Implementation is a little involved.

The AMP Cache will probably need to carefully consider lifetime issues, since documents are typically modified in this manner when ingested, not when served.

For example, the font you mentioned seems to be served with headers indicating it should not be cached publicly at all:

$ curl -i "https://fonts.googleapis.com/css?family=Muli|Open+Sans:400,700&amp;display=swap"
...
expires: Tue, 30 Jul 2019 21:11:30 GMT
date: Tue, 30 Jul 2019 21:11:30 GMT
cache-control: private, max-age=86400
...
vary: Accept-Encoding

It is marked to expire immediately, and cache-control: private suggests only a browser should cache this for up to 1 day, not an intermediary. This may be a lifetime issue, but it also may be only or in part due to the Accept-Encoding parameter in the request.

The Accept-Encoding variants would suggest that we can't do this for Signed Exchanges in any case.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.