First Init
Deploy to Production / Build & Verify (push) Failing after 5m56s
Ping Search Engines / Notify Search Engines (push) Successful in 2s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 2s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
E2E Test Suite / Smoke Tests (P0) (push) Failing after 11m26s
E2E Test Suite / Form Interaction Tests (push) Failing after 11m42s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 12m2s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 16m14s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 17m45s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 25m23s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 20s
E2E Test Suite / Mobile Device Tests (push) Failing after 2h49m9s
Uptime Monitor / Health & Response Time (push) Failing after 2s
Uptime Monitor / SSL Certificate (push) Successful in 2s
Uptime Monitor / Send Alerts (push) Failing after 3s
Uptime Monitor / Record Uptime Success (push) Has been skipped
Deploy to Production / Build & Verify (push) Failing after 5m56s
Ping Search Engines / Notify Search Engines (push) Successful in 2s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 2s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
E2E Test Suite / Smoke Tests (P0) (push) Failing after 11m26s
E2E Test Suite / Form Interaction Tests (push) Failing after 11m42s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 12m2s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 16m14s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 17m45s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 25m23s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 20s
E2E Test Suite / Mobile Device Tests (push) Failing after 2h49m9s
Uptime Monitor / Health & Response Time (push) Failing after 2s
Uptime Monitor / SSL Certificate (push) Successful in 2s
Uptime Monitor / Send Alerts (push) Failing after 3s
Uptime Monitor / Record Uptime Success (push) Has been skipped
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
# Core Web Vitals Optimization Report
|
||||
|
||||
**Date:** 2026-03-21
|
||||
**Agent:** performance-optimizer
|
||||
**Project:** WorkRoot IT Solutions (workroot.in)
|
||||
|
||||
---
|
||||
|
||||
## Baseline Performance (Pre-Optimization)
|
||||
|
||||
| Page | Performance | LCP | CLS | TBT |
|
||||
|------|-------------|-----|-----|-----|
|
||||
| Home | 98/100 | ✅ Good | ✅ < 0.1 | ✅ Low |
|
||||
| Services | 99/100 | ✅ Good | ✅ < 0.1 | ✅ Low |
|
||||
| Portfolio | 99/100 | ✅ Good | ✅ < 0.1 | ✅ Low |
|
||||
| About | 97/100 | ✅ Good | ✅ < 0.1 | ✅ Low |
|
||||
| Contact | 99/100 | ✅ Good | ✅ < 0.1 | ✅ Low |
|
||||
| Blog | 96/100 | ✅ Good | ✅ < 0.1 | ✅ Moderate |
|
||||
| **Average** | **98/100** | ✅ | ✅ | ✅ |
|
||||
|
||||
**Server:** TTFB ~213ms, ~9ms SSR processing, 33 req/sec
|
||||
|
||||
---
|
||||
|
||||
## Core Web Vitals Targets
|
||||
|
||||
| Metric | Target | Status |
|
||||
|--------|--------|--------|
|
||||
| LCP (Largest Contentful Paint) | < 2.5s | ✅ Already good |
|
||||
| INP (Interaction to Next Paint) | < 200ms | ✅ Already good |
|
||||
| CLS (Cumulative Layout Shift) | < 0.1 | ✅ Already good |
|
||||
|
||||
---
|
||||
|
||||
## Optimizations Implemented
|
||||
|
||||
### 1. Gzip/Brotli Compression — `server.mjs`
|
||||
|
||||
**Impact:** ~70% reduction in transfer size for HTML/CSS/JS responses.
|
||||
|
||||
Added `compression` Express middleware:
|
||||
```js
|
||||
import compression from 'compression';
|
||||
app.use(compression({ level: 6, threshold: 1024 }));
|
||||
```
|
||||
|
||||
- Level 6 balances compression ratio vs CPU overhead
|
||||
- Only compresses responses > 1KB (avoids overhead on tiny responses)
|
||||
- Respects `X-No-Compression` header for bypass
|
||||
|
||||
### 2. Static Asset Cache Headers — `server.mjs`
|
||||
|
||||
**Impact:** Near-instant repeat visits for returning users.
|
||||
|
||||
| Asset Type | Cache Duration | Strategy |
|
||||
|------------|----------------|----------|
|
||||
| `/_assets/*` (hashed) | 1 year | `immutable` — never re-fetch |
|
||||
| Fonts (`.woff2`, `.ttf`) | 1 year | `immutable` |
|
||||
| Images (`.webp`, `.png`, etc.) | 1 week | `stale-while-revalidate` |
|
||||
| Other static assets | 1 hour | `max-age` |
|
||||
|
||||
```js
|
||||
app.use('/_assets', express.static(path, {
|
||||
maxAge: '1y',
|
||||
immutable: true,
|
||||
}));
|
||||
```
|
||||
|
||||
### 3. Font Preload Hints — `BaseLayout.astro`
|
||||
|
||||
**Impact:** Eliminates render-blocking font load; faster FCP by ~200-400ms.
|
||||
|
||||
Replaced blocking `@import` with non-blocking load + preload hint:
|
||||
```html
|
||||
<link rel="preload" as="style"
|
||||
href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;700&display=swap"
|
||||
onload="this.onload=null;this.rel='stylesheet'" />
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="..." />
|
||||
</noscript>
|
||||
```
|
||||
|
||||
- Loads only the 2 critical weights (400/700) above-the-fold
|
||||
- Full variable font range still loaded via `global.css` for later content
|
||||
- `noscript` fallback ensures fonts load for users without JS
|
||||
|
||||
### 4. Enhanced Critical CSS — `BaseLayout.astro`
|
||||
|
||||
**Impact:** Faster FCP by rendering visible content immediately with correct styles.
|
||||
|
||||
Extended inlined critical CSS to include:
|
||||
- `body` now specifies `Plus Jakarta Sans` first (vs `system-ui` first) to prevent FOUT
|
||||
- `-moz-osx-font-smoothing: grayscale` for Firefox text rendering
|
||||
- `img { aspect-ratio: attr(width)/attr(height) }` — native CLS prevention
|
||||
- Above-fold Tailwind utility classes (`min-h-screen`, `flex`, `flex-col`, `items-center`)
|
||||
- `.animate-slide-up { animation-fill-mode: forwards }` — prevents animation flicker
|
||||
|
||||
### 5. Navigation Prefetch Strategy — `Header.astro` + `astro.config.mjs`
|
||||
|
||||
**Impact:** Navigation feels instant (~100-300ms faster perceived navigation).
|
||||
|
||||
- Added `data-astro-prefetch="hover"` to all desktop and mobile nav links
|
||||
- Changed `defaultStrategy` from `'viewport'` to `'hover'` in `astro.config.mjs`
|
||||
- `hover` strategy: prefetch starts when user hovers a link (150-200ms before click)
|
||||
- This gives the browser a head-start on the next page's HTML/assets
|
||||
|
||||
---
|
||||
|
||||
## Pre-Existing Optimizations (Already in Place)
|
||||
|
||||
The following were already well-implemented by previous work:
|
||||
|
||||
### Image Optimization ✅
|
||||
- Sharp image service for WebP conversion
|
||||
- Responsive `srcset` (320–1920px breakpoints)
|
||||
- Native `loading="lazy"` on all below-fold images
|
||||
- Aspect ratio wrappers on all images (CLS = 0)
|
||||
- Blur placeholder support via `imageUtils.ts`
|
||||
- `OptimizedImage.astro` and `LazyImage.astro` components
|
||||
|
||||
### CSS Architecture ✅
|
||||
- Tailwind CSS utility-first (no unused CSS)
|
||||
- CSS code splitting by route (`cssCodeSplit: true`)
|
||||
- `inlineStylesheets: 'auto'` inlines small CSS files
|
||||
- Critical CSS inlined in `BaseLayout.astro`
|
||||
|
||||
### JavaScript Minimization ✅
|
||||
- Zero heavy JS frameworks (no React bundle)
|
||||
- Astro SSR with minimal client-side JS
|
||||
- `compressHTML: true` minifies HTML output
|
||||
- Manual vendor chunk splitting for better caching
|
||||
|
||||
### Resource Hints ✅
|
||||
- `preconnect` to Google Fonts (`fonts.googleapis.com`, `fonts.gstatic.com`)
|
||||
- `preconnect` to Unsplash CDN
|
||||
- `dns-prefetch` for analytics providers
|
||||
- `preconnect` to GA4 and Plausible endpoints
|
||||
|
||||
### Server Performance ✅
|
||||
- TTFB: ~213ms (excellent for SSR)
|
||||
- SSR processing: ~9ms
|
||||
- Throughput: 33 req/sec
|
||||
|
||||
---
|
||||
|
||||
## Remaining Opportunities (Future)
|
||||
|
||||
| Opportunity | Impact | Complexity |
|
||||
|-------------|--------|------------|
|
||||
| CDN (Cloudflare/Fastly) | High — global latency reduction | Medium |
|
||||
| Self-hosted fonts | Medium — removes Google Fonts dependency | Low |
|
||||
| HTTP/2 Push | Low — preload critical assets | Medium |
|
||||
| Service Worker | Medium — offline support + cache | High |
|
||||
| Edge Rendering | High — reduce TTFB globally | High |
|
||||
| Image AVIF format | Low — ~20% smaller than WebP | Low |
|
||||
| Font subsetting | Low — smaller font files | Low |
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `server.mjs` | Added `compression` middleware + cache headers |
|
||||
| `src/layouts/BaseLayout.astro` | Font preload + enhanced critical CSS |
|
||||
| `src/components/Header.astro` | Added `data-astro-prefetch="hover"` to nav links |
|
||||
| `astro.config.mjs` | Changed prefetch strategy to `hover` |
|
||||
| `package.json` | Added `compression` dependency |
|
||||
|
||||
---
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
After deployment, verify with:
|
||||
|
||||
- [ ] [PageSpeed Insights](https://pagespeed.web.dev) — LCP < 2.5s, CLS < 0.1, INP < 200ms
|
||||
- [ ] [WebPageTest](https://webpagetest.org) — Check compression headers (`Content-Encoding: gzip`)
|
||||
- [ ] Browser DevTools Network tab — Verify `Cache-Control: public, max-age=31536000` on `/_assets/`
|
||||
- [ ] Chrome DevTools Lighthouse — Run audit on all 6 pages
|
||||
- [ ] [web.dev/measure](https://web.dev/measure) — Field data validation
|
||||
|
||||
### Expected Header Values
|
||||
|
||||
```
|
||||
# Static hashed assets
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
# Images
|
||||
Cache-Control: public, max-age=604800, stale-while-revalidate=86400
|
||||
|
||||
# HTML responses
|
||||
Content-Encoding: gzip
|
||||
Vary: Accept-Encoding
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The project was already exceptional (98/100 avg Lighthouse). The optimizations implemented target the remaining performance gaps:
|
||||
|
||||
1. **Compression** eliminates the biggest bandwidth bottleneck
|
||||
2. **Caching** makes repeat visits near-instant
|
||||
3. **Font preload** eliminates the last render-blocking resource
|
||||
4. **Prefetch on hover** makes navigation feel instantaneous
|
||||
|
||||
Expected improvement: **+1-2 Lighthouse points** on affected pages, with significant real-world improvement for repeat visitors (from cache) and first-time visitors on slow connections (from compression).
|
||||
Reference in New Issue
Block a user