03 — Frontend Performance: The Low Tier (Fonts, Preload, CSS Polish)
The 8 items roadmap.sh ranks Low Priority are the finishing polish — the tier you reach for once page weight, render-blocking, and image mechanics are already handled [1]. Most of it is fonts. Two of the eight are CSS housekeeping, one is proactive loading, and one closes the loop on dependencies. None of these will rescue a slow page; missing any of them on a fast page will leave a visible scar.
Fonts (the four-item cluster)
Four of the eight items live on web fonts, and they share one idea: a font is a request that blocks the text from painting.
- Use WOFF2 font format — WOFF2 is the smallest of the widely supported formats (Brotli-compressed, ~30% smaller than WOFF, far smaller than TTF/OTF). Browser support is universal on modern engines. Ship WOFF2 first; only add a WOFF fallback if you support a browser old enough to need it.
- Use preconnect to load your fonts faster — if your fonts live on a third-party host (Google Fonts, a CDN bucket on a different domain), the browser does DNS, TLS, and the round trip lazily on first request. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> in the head primes those handshakes early so the actual font request skips the preamble. crossorigin is mandatory — fonts are fetched with CORS (a cross-origin permission handshake).
- Keep the web font size under 300 KB — the 300 KB figure is roadmap.sh's threshold; the practical rule is "fewer glyphs, subset, the subset you actually use." A Latin-only body face subsets to ~30-60 KB; a full multilingual face balloons to megabytes until subset. Self-hosting the subset is the move; a single Google Fonts @import of an unsubsetted family is the failure mode.
- Prevent Flash or Invisible Text — FOIT (Flash Of Invisible Text) is the browser hiding text until the web font loads; FOUT (Flash Of Unstyled Text) is showing a fallback first, then swapping. The modern lever is the CSS font-display descriptor: optional for non-critical fonts (use fallback if web font doesn't arrive fast), swap for text that must show immediately, block (the FOIT default) only when a flash would actively harm. The trade is always "invisible text for a moment" vs "wrong font for a moment." Pick wrong-then-right; users read the fallback the instant it renders.
CSS housekeeping (the two items)
- Concatenate CSS into a single file — older rule, survives the HTTP/2 multiplexing era because request _cost_ (DNS, TLS, TTFB) still applies per file, and CSS is render-blocking by default. One shared, cacheable stylesheet outperforms many per-page ones for the second navigation. The exception: CSS that's only needed on one page can stay page-scoped if it's smaller than the shared download would be unused elsewhere.
- Remove unused CSS — the long-tail rule. Framework CSS (Bootstrap, Tailwind's pre-purge output, a design system you inherited) can ship 80% rules the page never matches. The Coverage tab in Chrome DevTools flags unused <style> and stylesheet rules; PurgeCSS or Tailwind's JIT handles it at build. The win compounds: smaller CSS = faster parse + faster style recalc on every interaction, not just first paint.
Proactive loading (one item)
- Pre-load URLs where possible — <link rel="preload"> for assets the page _will_ need but the HTML doesn't reference until later (a hero image declared in CSS, a critical font, the JSON endpoint fetched by the above-the-fold component). preload starts the fetch in parallel with parsing instead of waiting for the parser to discover it. The line: don't preload what isn't critical — preloading everything moves nothing, because the network queue is still finite.
The dependency tail (one item)
- Keep an eye on the size of dependencies — this is the _size_ counterpart to the Medium tier's "keep your dependencies up to date." Two angles. First, watch the entry bundle size in CI — a regression warning at +20 KB beats discovering it in Lighthouse a month later. Second, pull a Bundlephobia check on any new dep before adding it: a 5-line utility that drags 40 KB into the entry bundle is never the right call. The size of a page is the sum of the decisions you didn't notice making.
What "Low Priority" actually means
Low priority here isn't "unimportant" — it's "won't move the needle until you've earned it by handling the tiers above." Fonts and preload polish a page that's already fast; they won't rescue one that's slow. The closing habit, identical to the Medium tier: measure after each change, because the difference between "fixed FOIT" and "didn't" can be invisible until you watch the loading filmstrip. Lighthouse and WebPageTest both show the filmstrip; it's the single best tool for catching font regressions the numbers miss.
Eight items, mostly one asset, all of it the kind of tuning you do once and then protect. After this, the work is no longer _fixing_ — it's _defending_ the score.
References
- [1] roadmap.sh, "Frontend Performance Best Practices — Low Priority," roadmap.sh, 2024. [Online]. Available: https://roadmap.sh/frontend-performance-best-practices
- [2] MDN, "font-display," Mozilla, 2024. [Online]. Available: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display
- [3] web.dev, "Preload critical assets to improve loading speed," Google, 2024. [Online]. Available: https://web.dev/articles/preload-critical-assets
- [4] MDN, "preconnect," Mozilla, 2024. [Online]. Available: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preconnect
Comments
Leave a Comment
You must be signed in to comment
0 Comments
No comments yet. Be the first to comment!