Skip to content
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

feature: custom fonts with preloading #209

Merged
merged 11 commits into from
Jan 3, 2025
Merged

feature: custom fonts with preloading #209

merged 11 commits into from
Jan 3, 2025

Conversation

jbmoelker
Copy link
Member

@jbmoelker jbmoelker commented Nov 9, 2024

Changes

  • Adds custom font import strategy using Fontsource so font files are served from same domain and are automatically hashed for caching (when combined with perf: cache static assets (generated by Astro) #207).
  • Adds resource hints to preload the fonts for faster page rendering.

Note: based on #208 so the <PerfHead> could easily be extended.

Associated issue

Resolves #87

How to test

  1. Open preview link
  2. Verify a custom font is used for the page (body)
  3. Open DevTools > Network and verify font files are preloaded

Checklist

  • I have performed a self-review of my own code
  • I have made sure that my PR is easy to review (not too big, includes comments)
  • I have made updated relevant documentation files (in project README, docs/, etc) created follow-up issue Document assets setup #210
  • I have added a decision log entry if the change affects the architecture or changes a significant technology
  • I have notified a reviewer

Part of #87.

# To do

- [ ] add docs (assets/fonts/README.md?)
- [ ] use swap with Fontaine?
Copy link

cloudflare-workers-and-pages bot commented Nov 9, 2024

Deploying head-start with  Cloudflare Pages  Cloudflare Pages

Latest commit: e1f0cff
Status: ✅  Deploy successful!
Preview URL: https://3e3d893a.head-start.pages.dev
Branch Preview URL: https://feat-87-custom-fonts.head-start.pages.dev

View logs

src/assets/fonts.ts Outdated Show resolved Hide resolved
},
];

export const getFontCss = (font: Font) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: import raw (import archivo400css from '@fontsource/archivo/latin-400.css?raw';) is not an option as it results in font urls starting with ./files/... that are not resolved. So instead we generate the font declaration ourselves with the url that is resolved correctly in production.

Note 2: I've left out font-display: swap; as we don't have a fallback yet that doesn't cause a layout shift. See to do on Fontaine and font swap.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using fontaine seems a bit involved. Rather keep this PR small and merge this first, to add font swap as perf enhancement in a separate PR.

@jbmoelker jbmoelker requested a review from decrek November 9, 2024 15:05
@jbmoelker jbmoelker marked this pull request as ready for review November 9, 2024 17:30
Base automatically changed from perf/200-preconnect-origins to main November 11, 2024 19:27
jbmoelker added a commit that referenced this pull request Nov 27, 2024
Resolves #210

Note: #209 should be merged first.
@jbmoelker jbmoelker changed the title feat: custom fonts with preloading feature: custom fonts with preloading Nov 27, 2024
/>
))
}
<style set:text={criticalCss}></style>
Copy link
Member

@decrek decrek Jan 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think this serves any purpose since font files will only start to download when CSS is parsed and the browser knows wether there are characters on the screen that need a custom font. This is why font file downloads start late and we preload them with resource hints. Just a font face declaration will not cause the font to be downloaded.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or am I missing something?

If not, I think this PR can be "cleaned up" a lot. You could even remove the fonts.ts file all together since you only need the imports for the font files. So in perfhead something like this would be sufficient:

---
import archivo400url from '@fontsource/archivo/files/archivo-latin-400-normal.woff2?url';
import archivo600url from '@fontsource/archivo/files/archivo-latin-600-normal.woff2?url';

const fonts = [archivo400url, archivo600url]
---
<head>
    { fonts.map((font) => (
      <link rel="preload" href={ font } as="font" type="font/woff2" crossorigin />
    )) }
</head>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would still need to define the CSS declarations somewhere. It would make sense to me to do that in layouts/Default.astro

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checked again, and this does actually work. The reason being that both the critical CSS and the global core styles are inlined in the default layout. You can verify this on the the deploy preview. If you check the page source code you find both the font declarations (critical CSS) and the usage of the font family (might be easiest to search for --fontFamilyArchivo). Alternatively, you can check this in the UI by using the Chrome Network DevTools and blocking the CSS file (_astro/index.Cs0OcUxF.css) and verifying that the fonts are still loaded and applied.

@decrek decrek merged commit 0159b91 into main Jan 3, 2025
5 checks passed
@decrek decrek deleted the feat/87-custom-fonts branch January 3, 2025 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Custom Fonts
2 participants