Skip to content

Comments

chore: codebase optimization cleanup (P1-P4 complete, 10/12 tasks)#73

Open
jubalm wants to merge 5 commits intomainfrom
feature/optimization-tasks
Open

chore: codebase optimization cleanup (P1-P4 complete, 10/12 tasks)#73
jubalm wants to merge 5 commits intomainfrom
feature/optimization-tasks

Conversation

@jubalm
Copy link
Collaborator

@jubalm jubalm commented Feb 23, 2026

Summary

Codebase optimization consolidation across 4 priority levels. 10 of 12 tasks complete (83%).

Completed Priorities

P1: Quick Wins ✅ (3/3)

  • 1.1 Lint errors: Fixed 5 Biome violations (useless switch case, template literals, unused imports)
  • 1.2 Duplicate CSS: Removed duplicate @keyframes keycap-glow definition
  • 1.3 Dead code: Cleaned up unused props, variables, and imports across 5 components

P2: Performance ✅ (2/3)

  • 2.1 React memoization: Extracted pure helpers from ForkGauge (5 functions) and ForkDataProvider (3 functions), added useMemo + React.memo wrapping to eliminate unnecessary re-renders
  • 2.3 Font self-hosting: Downloaded Handjet (7.5KB) and Oxanium (14KB) as woff2, added @font-face to global.css, removed Google Fonts links (saves DNS roundtrip + CDN latency)
  • Note: 2.2 (viem migration) deferred to GH#72 for team input

P3: Developer Experience ✅ (4/4)

  • 3.1 TypeScript: Switched typecheck script from tsc --build to astro check (understands .astro files + Astro-aware diagnostics)
  • 3.2 CI gates: Added typecheck + lint steps to build job in .github/workflows/build-and-deploy.yml (gates every PR + push before build)
  • 3.3 Error boundaries: Created ErrorBoundary.tsx component, wrapped ForkMonitor tree to catch render-time exceptions with fallback UI
  • 3.4 Type fixes: Fixed TypeScript errors found by astro check (glob imports, JSX in Astro, deprecated React types, script directives)

P4: SEO/Accessibility ✅ (1/2)

  • 4.1 Reduce motion:
    • Added @media (prefers-reduced-motion: reduce) block to global.css with targeted animation disables
    • PerspectiveGridTunnel: Early return guard on motion preference, renders static frame only when motion reduced
    • ForkGauge: Conditionally disables needle transition when motion reduced
    • Respects OS accessibility settings without breaking visual hierarchy
  • Note: 4.2 (Structured data) moved to GH#74 (deferred for separate work)

P5: Architecture ⏸ (Deferred)

  • Skipped 5.1 (state docs) and 5.2 (testing) — lower priority than solidifying current optimization batch

Files Changed

Priority Files
P1 src/components/ForkStats.tsx, ForkDisplay.tsx, PerspectiveGridTunnel.tsx
P2 src/components/ForkGauge.tsx, ForkDataProvider.tsx; src/styles/global.css; public/fonts/ (new)
P3 package.json, .github/workflows/build-and-deploy.yml, src/components/ErrorBoundary.tsx, src/components/ForkMonitor.tsx, 5 Astro pages + components
P4 src/styles/global.css, src/components/PerspectiveGridTunnel.tsx, src/components/ForkGauge.tsx

Total impact: 240+ insertions, 57 deletions across 20+ files


Verification Checklist

  • npm run typecheck — 0 errors
  • npm run lint — 0 errors
  • npm run build — succeeds
  • Dev server: All animations render correctly
  • Demo mode (F2): Toggle all fork risk levels (None → Low → Medium → High → Critical)
  • Accessibility: Reduce motion enabled → animations disabled, gauge still interactive
  • Error boundary: Verified fallback renders on simulated render error

GitHub Issues

  • GH#72: Optimize: Migrate from ethers.js to viem (deferred for team input on dependencies)
  • GH#74: Optimize: Structured data JSON-LD (moved from P4.2, separate work track)

Next Steps

Ready to merge. All tests passing, no breaking changes. Site fully functional and optimized.

- Fix Biome lint errors (useless switch case, template literals, unused imports)
- Remove duplicate @Keyframes keycap-glow in global.css
- Remove dead code: unused props in ForkStats (now context-only)
- Clean up unused variables in PerspectiveGridTunnel
- Add worker-configuration.d.ts to .gitignore (Biome auto-ignores)
- Restore proper biome.json structure

Progress: 3/12 tasks complete (Priority 1 done)
## Task 2.1: React Component Optimization
- ForkGauge: Extract 5 pure helper functions outside component scope
  (getVisualPercentage, updateArc, getRiskLevel, getRiskColor, getNeedleEndpoint)
  Memoize computed values with useMemo to prevent unnecessary recalculations
  Wrap component with React.memo to prevent re-renders on prop equality

- ForkDataProvider: Move 3 converter functions outside component
  (convertToGaugeData, convertToRiskLevel, formatLastUpdated)
  Memoize contextValue with useMemo to prevent context consumers from re-rendering

## Task 2.3: Font Self-Hosting
- Download Handjet and Oxanium woff2 fonts from Google Fonts
- Add @font-face declarations to src/styles/global.css with local paths
- Remove Google Fonts CSS links and dns-prefetch from Layout.astro
- Fonts now load from /fonts/ instead of fonts.googleapis.com + fonts.gstatic.com

## Verification
- npm run typecheck: ✓ No TypeScript errors
- npm run lint: ✓ No Biome linting issues
- npm run build: ✓ Build succeeds with 21.3KB fonts bundled in dist/fonts/
- Font files: handjet.woff2 (7.5KB), oxanium.woff2 (14KB)
**Task 3.1 - Improve typecheck coverage**
- Switch from tsc --build to astro check (understands .astro files)
- Better Astro-aware diagnostics

**Task 3.2 - Add CI gates**
- Add typecheck step before build in GitHub Actions
- Add lint step before build in GitHub Actions
- Prevents type errors and lint violations from shipping

**Task 3.3 - React error boundaries**
- Create ErrorBoundary class component (src/components/ErrorBoundary.tsx)
- Wrap ForkMonitor render tree with ErrorBoundary
- Graceful fallback for render-time exceptions

**Task 3.4 - Fix TypeScript type errors**
- BlogPreview.astro: Type glob import properly, remove JSX key from HTML element
- blog/index.astro: Type glob import, fix autoFocus attribute
- blog/[...slug].astro: Type glob import, merge getImage() options
- GoogleAnalytics.astro: Add is:inline directives
- Layout.astro: Add is:inline directive to structured data script
- dialog.tsx: Replace deprecated React.ElementRef with concrete types

All checks pass:
- npm run typecheck: 0 errors
- npm run lint: 0 errors
- npm run build: succeeds
Add prefers-reduced-motion accessibility support across animations:

**CSS Animations (global.css)**
- Added @media (prefers-reduced-motion: reduce) block with targeted disables:
  - .title (gradient animation)
  - .cursor.blink-active (blink animation)
  - .pointer-animated, .pointer-animate-always (bounce animations)
  - .scroll-indicator-keycap (keycap press/glow animations)
  - .crt.display-on, .crt.display-off (CRT display animations)
  - .fx-pulse-glow (pulse effect)
  - Social media icon fade-ins (#twitter-link, #discord-link, #github-link)
  - HeroBanner entrance animations ([data-animation-delay])

**JavaScript Animations**
- PerspectiveGridTunnel: Check window.matchMedia() and skip animation loop
  for users with prefers-reduced-motion. Render single static frame instead.
- ForkGauge: Disable needle transition (set to 'none') when motion is reduced

All animations now gracefully respect user accessibility preferences.
Verified: typecheck 0 errors, lint 0 errors, build succeeds.
@jubalm jubalm changed the title chore: codebase optimization cleanup (P1 complete) chore: codebase optimization cleanup (P1-P4 complete, 10/12 tasks) Feb 23, 2026
@jubalm jubalm marked this pull request as ready for review February 23, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant