Skip to content

[Advanced]: perf(frontend): full Core Web Vitals audit and layout performance overhaul β€” target LCP <2.5s, CLS <0.1, INP <200msΒ #120

@ambicuity

Description

@ambicuity

🧠 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:

  1. No fetchpriority on jobs.json β€” competes with fonts at default priority
  2. body::before animated mesh gradient triggers paint on theme switch β€” needs contain: strict
  3. Blob animations (.blob-1/2/3) each have independent filter: blur(60px) β€” extremely expensive on mobile GPUs; need will-change: transform
  4. backdrop-filter: blur(20px) on every .job-card β€” 600+ GPU stacking contexts; must be scoped to .header only
  5. No content-visibility: auto on off-screen job cards
  6. meshFloat and blobFloat animations run regardless of prefers-reduced-motion
  7. No <link rel="preconnect"> for GoatCounter analytics host
  8. styles.css is 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-filter removed from .job-card; retained only on .header
  • contain: layout style paint on .jobs-container
  • will-change: transform on .blob-1/.blob-2/.blob-3
  • content-visibility: auto on .job-card
  • All animations halt under prefers-reduced-motion: reduce
  • GoatCounter <link rel="preconnect"> + dns-prefetch in <head>
  • jobs.json fetch uses priority: '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 contain changes
  • pre-commit run --all-files passes
  • 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/)

πŸ”— Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    accessibilityAccessibility and WCAG complianceadvancedRequires deep scraper knowledge; high-impact changehelp wantedExtra attention needed from the communityneeds-triageAwaiting maintainer review and categorizationperformancePerformance and Core Web Vitalstype: enhancementNew feature or requestui/uxFrontend UI and UX improvements

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions