# Performance Review — santhoshj.com

Date: 2026-04-11

## Lighthouse Scores

| Category | Desktop | Mobile |
|----------|---------|--------|
| Performance | 100 | 95 |
| Accessibility | 100 | 100 |
| Best Practices | 100 | 100 |
| SEO | 100 | 100 |

## Core Web Vitals

| Metric | Desktop | Mobile | Rating |
|--------|---------|--------|--------|
| FCP | 0.4s | 2.3s | Desktop: Great / Mobile: Needs improvement |
| LCP | 0.6s | 2.4s | Desktop: Great / Mobile: Good |
| TBT | 0ms | 0ms | Great |
| CLS | 0.001 | 0.001 | Great |
| SI | 0.5s | 2.4s | Desktop: Great / Mobile: Great |
| TTI | 0.6s | 2.4s | Desktop: Great / Mobile: Great |

LCP element: H1 text node (no image resource).

---

## Actionable Items (Priority Order)

### 1. Fix forced reflow — 48ms waste

- `setOpen()` at `index.html:502` causes 47ms forced sync layout
- `updateNotchTop()` at `index.html:623` also triggers reflow
- Root cause: reads geometric properties (e.g. `offsetWidth`) after DOM writes
- Fix: batch all layout reads before writes, or wrap writes in `requestAnimationFrame`

### 2. Add cache headers to JS bundles

- Astro-hashed JS assets served with `cache-control` TTL=0
- These files have content hashes in filenames — safe to cache long-term
- Fix: set `cache-control: public, max-age=31536000, immutable` on `/_astro/*` and other hashed assets
- Location: nginx config or CDN cache policy

### 3. Remove `cache-control: no-store` from HTML

- Current: HTML doc uses `no-store` → back/forward cache disabled
- Prevents instant back navigation (bfcache)
- Fix: replace `no-store` with `cache-control: max-age=0, must-revalidate`
- Also affects JS network requests receiving `no-store` resources

### 4. Tree-shake unused CSS — 30KB waste

- Two CSS chunks (16KB + 14KB) are entirely unused on the homepage
- Likely page-specific styles loaded eagerly
- Fix: ensure Astro code-splitting for CSS per page, or remove unused selectors
- Check `/_astro/_slug_.*.css` — may bundle all page styles into one sheet

### 5. Defer render-blocking JS — 550ms mobile waste

- Main JS bundle and CSS are render-blocking
- Fix: inline critical JS/CSS, defer remaining with `async` or `defer`
- Or: use `<link rel="preload">` for critical resources + `defer` for non-critical

### 6. Reduce unused JavaScript — 38KB / 99KB (38% waste)

- Main Astro JS bundle: 38KB unused out of 99KB
- Fix: audit Astro client-side scripts, remove unused island code, or split into smaller chunks
- Check if `setOpen`, `updateNotchTop`, umami analytics, and other inline scripts can be deferred

### 7. Optimize image delivery — 323KB mobile savings

- YouTube thumbnails served as-is (JPEG, no WebP/AVIF)
- No responsive `srcset` — full-size thumbnails on all viewports
- Fix: use `<picture>` with WebP/AVIF fallback, add `loading="lazy"` for below-fold images, consider `width`/`height` attributes to reduce CLS risk
- Note: these are 3rd-party `ytimg.com` URLs — limited control. Consider proxying or using YouTube's `mqdefault.jpg` (smaller) for mobile