web-app icon indicating copy to clipboard operation
web-app copied to clipboard

Load fonts progressively

Open mxmason opened this issue 5 years ago • 22 comments

Problem

Right now, the Typekit font bundle significantly slows page-load times. In limited local testing, it adds >1 second to load time on a simulated "average" 3G connection. This number increases significantly on lower-quality simulated connections, leading to average load times >5 seconds on "regular 2G" simulations.

Since a significant number of users browse the web on their phones, we should do our best to load these fonts progressively, so that they do not block user interaction on the page.

Proposal

Use Filament Group's LoadCSS library to bring support for link rel="preload" to all browsers.

With lazy-loading established, we can use it in the future for other non-critical styles that we may write for the app.

Benefits & trade-offs

➕ Page load time will decrease; user will be able to read, interact with our content sooner

➖ Browser may re-paint if there's a significant delay in loading the typekit bundle

mxmason avatar Mar 19 '20 19:03 mxmason

Thanks, @dengeist ! Sounds good.

I'm also wondering if as a multi-fold approach we can also upload/locally load the fonts as well and font-display: swap as well.

tatianamac avatar Mar 19 '20 19:03 tatianamac

This crossed my mind as well! All current browsers but IE 11 support the font-display property (source: caniuse), so we would have pretty good coverage if we moved to local font files. Additionally, hosting the fonts ourselves would cut out any reliance on TypeKit's servers. We might even get a bit of a site performance boost since we'd be minimizing requests to other domains.

Lazy-loading would still come in handy for users on older browsers that do not support font-display!

mxmason avatar Mar 19 '20 19:03 mxmason

Perfect! Would you be able to make those adjustments if I got you all the woffs? I haven't interacted with Typekit in a moment, but I believe that's all possible. Otherwise I will figure something out as a substitute.

Also when you say lazy-loading here do you mean preloading? (Or am I confuse?)

tatianamac avatar Mar 19 '20 20:03 tatianamac

I would be able to implement this if you got all the raw .woff files, yeah! If you can't, using rel="preload" and ensuring support for it should be a serviceable alternative!

(yes, by "lazy-loading", I do mean "preloading" here. preloading is lazy-loading in the context of CSS files.)

mxmason avatar Mar 19 '20 20:03 mxmason

Bad news is that Adobe Typekit does not allow download of .woff files. I can open up a cost to purchase directly from the foundry using funds from the Open Collective, but that will take time. In the meantime, do you have bandwidth to open a PR for what we discussed? (Apologies for the back and forth)

tatianamac avatar Mar 30 '20 19:03 tatianamac

Are you set on the current font? There are some great, open-source variable fonts out there that come with woff files. I've got some experience splitting up variable fonts to be speedy - I use Recursive on my personal site. It has a ton of variability.

https://www.recursive.design/

wuz avatar Mar 30 '20 20:03 wuz

While I love the spirit of Recursive, I'm not sure it encapsulates the vintage/brutish aesthetic I'm hoping to maintain.

Generally I'd be open to open-source fonts (heh) but I'd like that to be part of a broader examination of the full identity of the site (including logo/logomark/colours), which I'm in the process of exploring with a designer.

With that said for now, I'd like to proceed with the preload strategy @dengeist as we explore more comprehensive, branded solutions in the future.

tatianamac avatar Mar 30 '20 20:03 tatianamac

Gotcha, that definitely makes sense! Happy to help out however I can, regardless!

wuz avatar Mar 30 '20 21:03 wuz

Awesome! Thanks! Would you like to open a pull request per what @dengeist itemised above?

tatianamac avatar Mar 30 '20 21:03 tatianamac

@tatianamac, @wuz:

I was mistaken. I would like to propose that we close this issue as wontfix.

I was network-testing some unrelated work, and realized that the way Chrome labels its network-throttling settings is misleading: its "Regular 3G" profile is somehow several orders of magnitude slower than Firefox's "Regular 2G." I could not find concrete bandwidth settings for Chrome's default network profiles, but I could find Firefox's profiles.

I made a custom profile on Chrome based on Firefox's "Regular 2G", to ensure parity, then tested the current live SelfDefined site. On this setting, both browsers hit the DOMContentLoaded stage at ~1.2s and full Load at ~2.2s. This, I think, is an acceptable speed for a 2G environment. Performing the same test with rel="preload" and polyfills in place, load time is actually worse, averaging ~5s for full load.

I'm not sure why these numbers are so different from my original report. It could be that loading typekit as a link really helped us out, since @import blocks the rendering thread and link tags do not. I did not test speeds again after making that change!

All this to say that if everyone here thinks the current speeds are acceptable, we can leave fonts alone until such a time as we can utilize display=swap. I apologize for taking up folks' time with my mistake.

mxmason avatar Apr 02 '20 06:04 mxmason

All this to say that if everyone here thinks the current speeds are acceptable, we can leave fonts alone until such a time as we can utilize display=swap.

The good news is: Adobe is probably working on bringing font-display: swap to Adobe Fonts. The bad news: There is no update since January.

See: https://community.adobe.com/t5/adobe-fonts/possible-to-set-font-display-swap/m-p/10730659?page=1#

Edit: Asked on Twitter. No ETA. https://twitter.com/AdobeFonts/status/1245744051825127424

ovlb avatar Apr 02 '20 15:04 ovlb

@dengeist @ovlb Thanks for looking into this so intently!

I went ahead and purchased the fonts for this. Attached is the zip file of all the fonts .woff and .woff2 files. That way, we can avoid TypeKit altogether.

MyFontsWebfontsKit.zip

tatianamac avatar Apr 10 '20 02:04 tatianamac

Why didn’t I get a mail that something happened here? Can I grab this issue and implement the fonts locally?

There might be an issue with copyright though. I think the MyFonts terms forbid to host the files in a public repo. What I do with my personal sites that use commercial fonts: put them in a separate, private repo, add this to Netlify as static.domain.com and use this URL in the @font-face declaration.

ovlb avatar Apr 19 '20 08:04 ovlb

@ovlb Yes, you can grab the issue. 💙 Is it possible to just .gitignore the font-files themselves so that they're hosted but not published on the repo?

tatianamac avatar Apr 20 '20 16:04 tatianamac

@tatianamac From my understanding of the .gitignore they will not leave my computer once I add them there. And as as such also not end up on Netlify

ovlb avatar Apr 20 '20 16:04 ovlb

@ovlb keep in mind that, however we choose to approach this problem, using @font-face to load fonts is a render-blocking operation, where assets in <link /> tags aren't. We'd be back to the perf problem that inspired this change

mxmason avatar Apr 20 '20 16:04 mxmason

@tatianamac I think I found a solution for the font hosting problem by staring at the Internet long enough. Netlify recently introduced build plugins and there is one to encrypt files, which Netlify can decrypt. I will give it a whirl :) https://github.com/sw-yx/netlify-plugin-encrypted-files

ovlb avatar May 05 '20 21:05 ovlb

Can't wait!

(Also I hope you're able to take care of yourself during these weird times. 💙)

tatianamac avatar May 07 '20 21:05 tatianamac

@tatianamac I gave it a try with a demo project and it works fine. But I think it isn’t the solution we want. As the fonts are hosted encrypted in the repo, we would have to hand out the secret key to everyone working on the project, or they will see no web fonts. If we do this, we are back at the issue that distributing the font files is illegal.

My proposal for hosting them is to create a private repo (maybe selfdefined/static in a selfdefined GitHub org?) to which only people directly working with these files have access. As GitHub made private repos free for orgs, this isn’t a cost factor anymore.

Once done we can reference the files in our font-face declaration by using something like url('https://static.selfdefined.app/fonts/xyz.woff2). This way all contributors can enjoy the web fonts, and we don’t have to worry about MyFonts going after you.

ovlb avatar May 11 '20 13:05 ovlb

@ovlb ! Thanks for looking into this.

I feel like as I'm in the midst of a branding project, I this forces a compelling reason to switch to fonts with a licence more amenable to our needs.

For now, I think your solution makes sense! If we'd like to migrate to a private repo/org, it also might be good to consider migrating to a selfdefined specific GitHub org? I'm curious if you've ever done this sort of a migration. Also I can open up a new ticket so we can have this discussion there and make that a block for this issue.

tatianamac avatar May 11 '20 21:05 tatianamac

@tatianamac Discussing this in a separate ticket makes sense. :)

ovlb avatar May 12 '20 11:05 ovlb

Repinging this thread now that we have selfdefined on its own repo

tatianamac avatar Sep 02 '20 20:09 tatianamac