-
Notifications
You must be signed in to change notification settings - Fork 14
Description
π§ Advanced Contributors
This issue requires deep familiarity with:
- Chrome DevTools Performance panel, Lighthouse, Web Vitals extension
- CSS
contain,will-change,content-visibility: auto - HTML resource hints (
<link rel="preconnect">,fetchpriority) - Critical CSS extraction and non-critical style deferral
- The full
docs/frontend stack
Important
You must be assigned before starting β comment /assign to claim this issue.
Measure baseline Lighthouse scores FIRST before making any changes. PRs without before/after Lighthouse screenshots will not be reviewed.
Warning
Changes to backdrop-filter, contain, and will-change can cause visual regressions if applied incorrectly. Test in Chrome, Firefox, and Safari β both dark and light themes β before opening the PR.
π Problem Description
Pre-audit analysis of the production site reveals these structural performance gaps:
| Metric | Estimated Current | Target |
|---|---|---|
| LCP (Largest Contentful Paint) | ~3.5β5s (4G mobile) | < 2.5s |
| CLS (Cumulative Layout Shift) | ~0.15β0.3 | < 0.1 |
| INP (Interaction to Next Paint) | ~400β900ms on filter | < 200ms |
| Total Blocking Time | ~800ms | < 300ms |
Root causes:
- No
fetchpriorityonjobs.jsonβ competes with fonts at default priority body::beforeanimated mesh gradient triggers paint on theme switch β needscontain: strict- Blob animations (
.blob-1/2/3) each have independentfilter: blur(60px)β extremely expensive on mobile GPUs; needwill-change: transform backdrop-filter: blur(20px)on every.job-cardβ 600+ GPU stacking contexts; must be scoped to.headeronly- No
content-visibility: autoon off-screen job cards meshFloatandblobFloatanimations run regardless ofprefers-reduced-motion- No
<link rel="preconnect">for GoatCounter analytics host styles.cssis 42KB monolithic β no critical CSS inlined; fully render-blocking
π‘ Proposed / Expected Solution
Step A: Measure baseline β Lighthouse β Mobile β Navigation β 4G throttling. Screenshot scores, paste into PR.
Step B: CSS fixes in docs/styles.css:
/* .jobs-container */
contain: layout style paint;
/* .blob-1, .blob-2, .blob-3 */
will-change: transform;
/* REMOVE backdrop-filter from .job-card β keep ONLY on .header */
/* .job-card */
content-visibility: auto;
contain-intrinsic-size: 0 80px;
/* Halt animations for reduced-motion users */
@media (prefers-reduced-motion: reduce) {
.blob, body::before { animation: none; }
}Step C: Resource hints in docs/index.html <head>:
<link rel="preconnect" href="https://gc.zgo.at" crossorigin>
<link rel="dns-prefetch" href="https://gc.zgo.at">In docs/app.js:
fetch('jobs.json', { priority: 'high' })Step D: Critical CSS extraction β Inline the minimum CSS for above-the-fold (header + hero) as <style> in <head>. Defer the rest:
<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>Step E: Measure again β same Lighthouse settings. Document after scores in PR.
β Acceptance Criteria
- Lighthouse mobile LCP β€ 2.5s β before/after screenshots in PR (mandatory)
- Lighthouse mobile CLS β€ 0.1
- INP β€ 200ms on filter chip interactions
-
backdrop-filterremoved from.job-card; retained only on.header -
contain: layout style painton.jobs-container -
will-change: transformon.blob-1/.blob-2/.blob-3 -
content-visibility: autoon.job-card - All animations halt under
prefers-reduced-motion: reduce - GoatCounter
<link rel="preconnect">+dns-prefetchin<head> -
jobs.jsonfetch usespriority: 'high' - No functional regression β filters, search, bookmarks, theme toggle all work
- Dark and light themes visually correct in Chrome, Firefox, Safari
- Zero critical axe-core errors after
containchanges -
pre-commit run --all-filespasses - Existing tests pass (
make test) - PR description has before/after Lighthouse scores (mobile, 4G throttled)
- PR linked with
Fixes #<number> - PR title:
perf(frontend): core web vitals overhaul β LCP, CLS, INP targets met
Area: π Frontend / website (docs/)