Conversation
…TechMono, CLS fallback metrics Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
There was a problem hiding this comment.
Pull request overview
Optimizes font loading across the static site to reduce render-blocking requests and mitigate CLS during webfont swaps by preloading critical Inter and loading non-critical fonts asynchronously; also updates generation templates so newly generated pages inherit the same strategy.
Changes:
- Added CSS
@font-facemetric overrides intended to stabilize layout during font swap. - Split Google Fonts loading into: Inter (blocking + preload) and non-critical fonts (async via print/onload + noscript fallback).
- Updated page templates so generated news indexes and articles use the new loading pattern.
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| styles.css | Adds font fallback metric overrides intended to reduce CLS. |
| scripts/generate-news-indexes/template.ts | Updates generated news index pages to preload Inter + async Orbitron. |
| scripts/article-template/template.ts | Updates generated articles to preload Inter + async Orbitron/Share Tech Mono. |
| politician-dashboard.html | Applies preload/async font loading split to the politician dashboard page. |
| index.html | Applies preload/async font loading split to the EN landing page. |
| index_ar.html | Applies preload/async font loading split to the AR landing page. |
| index_da.html | Applies preload/async font loading split to the DA landing page. |
| index_de.html | Applies preload/async font loading split to the DE landing page. |
| index_es.html | Applies preload/async font loading split to the ES landing page. |
| index_fi.html | Applies preload/async font loading split to the FI landing page. |
| index_fr.html | Applies preload/async font loading split to the FR landing page. |
| index_he.html | Applies preload/async font loading split to the HE landing page. |
| index_ja.html | Applies preload/async font loading split to the JA landing page. |
| index_ko.html | Applies preload/async font loading split to the KO landing page. |
| index_nl.html | Applies preload/async font loading split to the NL landing page. |
| index_no.html | Applies preload/async font loading split to the NO landing page. |
| index_sv.html | Applies preload/async font loading split to the SV landing page. |
| index_zh.html | Applies preload/async font loading split to the ZH landing page. |
| dashboard/index.html | Applies preload/async font loading split (incl. async Noto families) to dashboard EN. |
| dashboard/index_ar.html | Applies preload/async font loading split (incl. async Noto families) to dashboard AR. |
| dashboard/index_da.html | Applies preload/async font loading split (incl. async Noto families) to dashboard DA. |
| dashboard/index_de.html | Applies preload/async font loading split (incl. async Noto families) to dashboard DE. |
| dashboard/index_es.html | Applies preload/async font loading split (incl. async Noto families) to dashboard ES. |
| dashboard/index_fi.html | Applies preload/async font loading split (incl. async Noto families) to dashboard FI. |
| dashboard/index_fr.html | Applies preload/async font loading split (incl. async Noto families) to dashboard FR. |
| dashboard/index_he.html | Applies preload/async font loading split (incl. async Noto families) to dashboard HE. |
| dashboard/index_ja.html | Applies preload/async font loading split (incl. async Noto families) to dashboard JA. |
| dashboard/index_ko.html | Applies preload/async font loading split (incl. async Noto families) to dashboard KO. |
| dashboard/index_nl.html | Applies preload/async font loading split (incl. async Noto families) to dashboard NL. |
| dashboard/index_no.html | Applies preload/async font loading split (incl. async Noto families) to dashboard NO. |
| dashboard/index_sv.html | Applies preload/async font loading split (incl. async Noto families) to dashboard SV. |
| dashboard/index_zh.html | Applies preload/async font loading split (incl. async Noto families) to dashboard ZH. |
| @font-face { | ||
| font-family: 'Inter'; | ||
| font-style: normal; | ||
| font-weight: 100 900; | ||
| font-display: swap; |
There was a problem hiding this comment.
The new @font-face rule defines font-family "Inter" with only local('Arial') sources. Because styles.css is loaded after the Google Fonts stylesheet, this rule can override the webfont @font-face definitions for Inter (same family/style/weight range), causing the site to render in Arial and never use the downloaded Inter files. Use a distinct fallback family name (e.g., "Inter Fallback") and reference it in the font-family stack, or otherwise ensure these fallback-metric faces don’t override the real webfont faces.
There was a problem hiding this comment.
Fixed in 1e8716a. Renamed the fallback @font-face family from 'Inter' to 'Inter Fallback' so it no longer conflicts with the Google Fonts webfont declaration. Added "Inter Fallback" as the second entry in all Inter-based font-family stacks (--font-main, --font-accent, Noto stacks, and direct references).
| @font-face { | ||
| font-family: 'Orbitron'; | ||
| font-style: normal; | ||
| font-weight: 700; | ||
| font-display: swap; |
There was a problem hiding this comment.
Same issue as above for Orbitron: this local-only @font-face for font-family "Orbitron" can override the Google Fonts Orbitron faces since it’s declared in styles.css. That would prevent the actual Orbitron webfont from ever being used. Consider moving these metric overrides to separate fallback family names and using them in the font-family fallback list.
There was a problem hiding this comment.
Fixed in 1e8716a. Renamed the fallback @font-face family from 'Orbitron' to 'Orbitron Fallback' and added "Orbitron Fallback" to every Orbitron-based font-family declaration in styles.css (--font-accent, dark-mode heading rule, .news-page h1, .chart-empty-state h3, .chart-error-state h3, and all var(--font-heading, ...) fallbacks).
scripts/article-template/template.ts
Outdated
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700&family=Share+Tech+Mono&display=swap" media="print" onload="this.media='all'"> | ||
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700&family=Share+Tech+Mono&display=swap"></noscript> |
There was a problem hiding this comment.
Orbitron is now requested with only wght@700, but the CSS applies Orbitron to headings that still request other weights (e.g., base h1/h2 use 600 and h3 uses 500; news-page h1 inherits 600). This will force synthetic weights or fallback, which can undermine the intended CLS/typography improvements. Either load the additional Orbitron weights actually used, or update the relevant heading rules to use font-weight: 700 when Orbitron is active.
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700&family=Share+Tech+Mono&display=swap" media="print" onload="this.media='all'"> | |
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700&family=Share+Tech+Mono&display=swap"></noscript> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&display=swap" media="print" onload="this.media='all'"> | |
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&display=swap"></noscript> |
There was a problem hiding this comment.
Fixed in 1e8716a. Orbitron now loads wght@500;600;700 across all 29 HTML pages and both templates, matching the h1/h2 (font-weight: 600) and h3 (font-weight: 500) heading rules in styles.css.
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> | ||
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700&display=swap" media="print" onload="this.media='all'"> | ||
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700&display=swap"></noscript> |
There was a problem hiding this comment.
This template now loads Orbitron with only wght@700, but styles.css applies Orbitron to the news page H1 without setting font-weight, so it inherits the global h1 font-weight (600). With only 700 available, browsers will synthesize or fallback. Consider aligning the CSS heading weights with 700 or loading the weights that are actually used on news pages.
There was a problem hiding this comment.
Fixed in 1e8716a. generate-news-indexes/template.ts now loads Orbitron:wght@500;600;700, covering the inherited font-weight: 600 on news-page h1.
|
@copilot apply changes based on the comments in this thread |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
… load Orbitron wght@500;600;700 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
All four review comments addressed in 1e8716a:
|
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
dashboard/index_zh.html
Outdated
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Orbitron:wght@400;500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" rel="stylesheet"> | ||
| <link rel="preload" href="https://fonts.gstatic.com/s/inter/v18/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa2JL7.woff2" as="font" type="font/woff2" crossorigin> | ||
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> | ||
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> |
There was a problem hiding this comment.
This page’s primary font for :lang(zh) content is Noto Sans SC (per styles.css), but Noto is now loaded via an async media="print" stylesheet. That can cause an initial render in Inter/system fonts followed by a late swap to Noto, increasing CLS for CJK users. Consider keeping the required Noto family as a blocking stylesheet (or preload its critical subset) and only async-load non-critical fonts like Orbitron/Share Tech Mono.
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | |
| <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> |
There was a problem hiding this comment.
Fixed in eb8fa2a. dashboard/index_zh.html now loads Noto Sans SC as a blocking stylesheet alongside Inter; the remaining 4 Noto families stay in the async bundle.
dashboard/index_ja.html
Outdated
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | ||
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> |
There was a problem hiding this comment.
This page’s primary font for :lang(ja) content is Noto Sans JP (per styles.css), but it’s currently included in the async media="print" Google Fonts stylesheet. That can cause an initial render in fallback fonts and a late swap to Noto, increasing CLS. Consider loading the needed Noto family synchronously (or preloading a critical subset) while keeping Orbitron/Share Tech Mono async.
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | |
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> | |
| <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | |
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> |
There was a problem hiding this comment.
Fixed in eb8fa2a. dashboard/index_ja.html now loads Noto Sans JP as a blocking stylesheet; the other Noto families remain async.
dashboard/index_ko.html
Outdated
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | ||
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> |
There was a problem hiding this comment.
This page’s primary font for :lang(ko) content is Noto Sans KR (per styles.css), but Noto is now loaded via an async media="print" stylesheet. That can increase CLS when text swaps to Noto after initial paint. Consider loading the required Noto family as a blocking stylesheet (or preloading its critical subset) and only async-loading non-critical fonts.
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | |
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> | |
| <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | |
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> |
There was a problem hiding this comment.
Fixed in eb8fa2a. dashboard/index_ko.html now loads Noto Sans KR as a blocking stylesheet; the other Noto families remain async.
dashboard/index_ar.html
Outdated
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | ||
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> |
There was a problem hiding this comment.
This page’s primary font for :lang(ar) content is Noto Sans Arabic (per styles.css), but it’s included in the async media="print" Google Fonts stylesheet. That can cause late font swapping and added CLS for RTL users. Consider loading the required Noto family synchronously (or preloading a critical subset) while keeping Orbitron/Share Tech Mono async.
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | |
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> | |
| <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Arabic:wght@400;500;700&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | |
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> |
There was a problem hiding this comment.
Fixed in eb8fa2a. dashboard/index_ar.html now loads Noto Sans Arabic as a blocking stylesheet; the other Noto families remain async.
dashboard/index_he.html
Outdated
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | ||
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> |
There was a problem hiding this comment.
This page’s primary font for :lang(he) content is Noto Sans Hebrew (per styles.css), but it’s currently loaded via an async media="print" stylesheet. That can cause a late swap to Noto and increase CLS for RTL users. Consider loading the required Noto family synchronously (or preloading a critical subset) and only async-loading non-critical fonts.
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | |
| <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"></noscript> | |
| <!-- Critical font for Hebrew content: load Noto Sans Hebrew synchronously to avoid layout shifts --> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"> | |
| <!-- Non-critical fonts loaded asynchronously --> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&display=swap" media="print" onload="this.media='all'"> | |
| <noscript> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+Hebrew:wght@400;500;700&display=swap"> | |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Sans+KR:wght@400;500;700&family=Noto+Sans+SC:wght@400;500;700&family=Noto+Sans+Arabic:wght@400;500;700&display=swap"> | |
| </noscript> |
There was a problem hiding this comment.
Fixed in eb8fa2a. dashboard/index_he.html now loads Noto Sans Hebrew as a blocking stylesheet; the other Noto families remain async.
| @font-face { | ||
| font-family: 'Inter Fallback'; | ||
| font-style: normal; | ||
| font-weight: 100 900; | ||
| font-display: swap; | ||
| size-adjust: 107%; | ||
| ascent-override: 90%; | ||
| descent-override: 22%; | ||
| line-gap-override: 0%; | ||
| src: local('Arial'); | ||
| } |
There was a problem hiding this comment.
The Inter fallback-metrics face only sources local('Arial'). On platforms without Arial (common on Linux/Android variants), the entire @font-face will be ignored, so size-adjust/override metrics won’t apply and CLS improvements won’t benefit those users. Consider adding additional widely-available local fallbacks (e.g., Liberation Sans/Helvetica/Noto Sans) or otherwise ensuring the fallback face resolves cross-platform.
There was a problem hiding this comment.
Fixed in eb8fa2a. Added local('Liberation Sans'), local('Helvetica Neue'), local('Helvetica') to the Inter Fallback src list, covering Linux (Liberation Sans) and macOS (Helvetica Neue/Helvetica).
| @font-face { | ||
| font-family: 'Orbitron Fallback'; | ||
| font-style: normal; | ||
| font-weight: 500 700; | ||
| font-display: swap; | ||
| size-adjust: 94%; | ||
| ascent-override: 85%; | ||
| descent-override: 15%; | ||
| line-gap-override: 0%; | ||
| src: local('Arial Black'), local('Impact'); | ||
| } |
There was a problem hiding this comment.
Same portability issue for the Orbitron fallback-metrics face: local('Arial Black'), local('Impact') are not reliably present across OSes, so the metric-adjusted fallback may not resolve and CLS may remain. Consider expanding the src: local(...) list with common cross-platform alternatives (or provide separate metric faces per OS family).
There was a problem hiding this comment.
Fixed in eb8fa2a. Added local('Century Gothic') (Windows) and local('Trebuchet MS') (widely available) to the Orbitron Fallback src list alongside the existing Arial Black and Impact entries.
|
@copilot apply changes based on the comments in this thread |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
…s; broaden fallback font sources Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
All seven comments addressed in eb8fa2a:
|
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
Three font families loaded as a single blocking stylesheet caused render-blocking requests and CLS on font-swap. Orbitron was loaded with 4 weights despite only being used at
500–700for headings.CSS (
styles.css)@font-facefallback metric overrides using distinct family names'Inter Fallback'and'Orbitron Fallback'—size-adjust,ascent-override,descent-override,line-gap-overrideapproximate each web font's metrics, eliminating layout shift during the swap without overriding the real webfont declarationsInter Fallbacksources:local('Arial'),local('Liberation Sans'),local('Helvetica Neue'),local('Helvetica')for cross-platform coverage (Windows, Linux, macOS, Android)Orbitron Fallbacksources:local('Arial Black'),local('Impact'),local('Century Gothic'),local('Trebuchet MS')for cross-platform coveragefont-familystacks (--font-main,--font-accent, dark-mode heading rule,.news-page h1, chart state headings,var(--font-heading, ...)fallbacks)HTML — all 29 pages (14 root
index*.html, 14dashboard/index*.html,politician-dashboard.html)Split one blocking
<link>into targeted tags:Orbitron loads
wght@500;600;700to match h1/h2 (font-weight: 600) and h3 (font-weight: 500) heading rules, avoiding synthetic weight rendering.CJK/RTL dashboard pages — language-specific Noto font loaded synchronously
For the five dashboard pages whose primary content font is a Noto family, that family is now loaded as a blocking stylesheet (alongside Inter) to prevent a late font swap and CLS for those users. The remaining Noto families stay in the async bundle:
dashboard/index_zh.htmldashboard/index_ja.htmldashboard/index_ko.htmldashboard/index_ar.htmldashboard/index_he.htmlTemplates (
scripts/article-template/template.ts,scripts/generate-news-indexes/template.ts)Applied the same pattern so newly generated articles inherit the optimized loading strategy.
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.