auto-claude: subtask-2-1 - Run baseline PageSpeed audit using existing script
Created comprehensive PERFORMANCE_BASELINE.md documenting: - Target thresholds from performance.spec.ts (90% all categories) - Current optimizations (AVIF/WebP, font swap, preconnect, cache headers) - Critical issues: hero-portrait.jpg (2.9MB), portrait.jpg (1.2MB) - 13 client components identified for potential RSC conversion - Prioritized action items for optimization Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,327 @@
|
||||
# Performance Baseline Report
|
||||
|
||||
**Date:** 2025-01-25
|
||||
**URL:** https://www.damjan-savic.com/
|
||||
**Framework:** Next.js 15.1 with React 19
|
||||
**Methodology:** Code analysis + Playwright-Lighthouse test configuration
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This baseline report documents the current performance state of the portfolio website based on code analysis and the existing performance test infrastructure. The site targets **90% scores** across all Lighthouse categories (Performance, Accessibility, Best Practices, SEO).
|
||||
|
||||
---
|
||||
|
||||
## Target Thresholds (from `tests/e2e/performance.spec.ts`)
|
||||
|
||||
| Category | Target | Status |
|
||||
|---------------|--------|---------------|
|
||||
| Performance | ≥90% | To be tested |
|
||||
| Accessibility | ≥90% | To be tested |
|
||||
| Best Practices| ≥90% | To be tested |
|
||||
| SEO | ≥90% | To be tested |
|
||||
|
||||
### Core Web Vitals Targets
|
||||
|
||||
| Metric | Good | Needs Improvement | Poor |
|
||||
|--------|------|-------------------|------|
|
||||
| LCP (Largest Contentful Paint) | ≤2.5s | 2.5s - 4.0s | >4.0s |
|
||||
| INP (Interaction to Next Paint) | ≤200ms | 200ms - 500ms | >500ms |
|
||||
| CLS (Cumulative Layout Shift) | ≤0.1 | 0.1 - 0.25 | >0.25 |
|
||||
| FCP (First Contentful Paint) | ≤1.8s | 1.8s - 3.0s | >3.0s |
|
||||
| TBT (Total Blocking Time) | ≤200ms | 200ms - 600ms | >600ms |
|
||||
|
||||
---
|
||||
|
||||
## Current Optimizations Analysis
|
||||
|
||||
### ✅ Positive Findings (Already Implemented)
|
||||
|
||||
#### 1. Image Optimization
|
||||
```typescript
|
||||
// next.config.ts
|
||||
images: {
|
||||
formats: ['image/avif', 'image/webp'],
|
||||
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
|
||||
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
||||
}
|
||||
```
|
||||
- **Status:** ✅ Modern formats (AVIF, WebP) configured
|
||||
- **Impact:** Reduces image payload by 25-50%
|
||||
|
||||
#### 2. Font Loading Strategy
|
||||
```typescript
|
||||
const inter = Inter({
|
||||
subsets: ['latin'],
|
||||
display: 'swap',
|
||||
variable: '--font-inter',
|
||||
});
|
||||
```
|
||||
- **Status:** ✅ Font swap prevents FOIT (Flash of Invisible Text)
|
||||
- **Impact:** Improved LCP and user experience
|
||||
|
||||
#### 3. Resource Hints
|
||||
```html
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||
<link rel="dns-prefetch" href="https://mxadgucxhmstlzsbgmoz.supabase.co" />
|
||||
```
|
||||
- **Status:** ✅ Critical third-party connections pre-established
|
||||
- **Impact:** Reduces connection latency by 100-300ms
|
||||
|
||||
#### 4. Static Generation
|
||||
```typescript
|
||||
export function generateStaticParams() {
|
||||
return locales.map((locale) => ({ locale }));
|
||||
}
|
||||
```
|
||||
- **Status:** ✅ All locale routes pre-rendered at build time
|
||||
- **Impact:** Zero server-side rendering delay
|
||||
|
||||
#### 5. Package Import Optimization
|
||||
```typescript
|
||||
experimental: {
|
||||
optimizePackageImports: ['lucide-react', 'framer-motion'],
|
||||
}
|
||||
```
|
||||
- **Status:** ✅ Tree-shaking for large icon/animation libraries
|
||||
- **Impact:** Reduces bundle size by 50-80% for these packages
|
||||
|
||||
#### 6. Cache Headers
|
||||
```typescript
|
||||
{
|
||||
source: '/images/:path*',
|
||||
headers: [{ key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }],
|
||||
}
|
||||
```
|
||||
- **Status:** ✅ Aggressive caching for static assets (1 year)
|
||||
- **Impact:** Eliminates re-download on repeat visits
|
||||
|
||||
#### 7. Production Console Removal
|
||||
```typescript
|
||||
compiler: {
|
||||
removeConsole: process.env.NODE_ENV === 'production',
|
||||
}
|
||||
```
|
||||
- **Status:** ✅ No console pollution in production
|
||||
- **Impact:** Smaller bundle, cleaner performance profile
|
||||
|
||||
#### 8. Priority Image Loading
|
||||
```typescript
|
||||
<Image src="/hero-portrait.jpg" priority />
|
||||
<Image src="/header-logo.svg" priority />
|
||||
```
|
||||
- **Status:** ✅ Critical images loaded with high priority
|
||||
- **Impact:** Faster LCP
|
||||
|
||||
#### 9. Structured Data (JSON-LD)
|
||||
- PersonJsonLd, ProfessionalServiceJsonLd, OrganizationJsonLd, WebSiteJsonLd
|
||||
- **Status:** ✅ Comprehensive schema markup
|
||||
- **Impact:** Better search engine understanding and rich results
|
||||
|
||||
#### 10. Responsive Image Variants
|
||||
Pre-generated sizes: 224, 288, 300, 448, 576, 600px (WebP and JPG)
|
||||
- **Status:** ✅ Multiple sizes for different viewports
|
||||
- **Impact:** Optimal image delivery per device
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Optimization Opportunities Identified
|
||||
|
||||
### 1. CRITICAL: Unoptimized Hero Image
|
||||
|
||||
**File:** `/public/hero-portrait.jpg`
|
||||
**Size:** 2,957,516 bytes (~2.9 MB)
|
||||
**Impact:** Major LCP delay
|
||||
|
||||
**Recommendation:**
|
||||
- Compress to <500KB (80-85% JPEG quality)
|
||||
- Use Next.js Image component with blur placeholder
|
||||
- Consider AVIF format for additional savings
|
||||
- Add `fetchpriority="high"` attribute
|
||||
|
||||
**Potential Savings:** 2.0-2.5 MB (60-85% reduction)
|
||||
|
||||
---
|
||||
|
||||
### 2. HIGH: Large Portrait Image
|
||||
|
||||
**File:** `/public/portrait.jpg`
|
||||
**Size:** 1,207,506 bytes (~1.2 MB)
|
||||
**Impact:** Page weight, especially on portfolio pages
|
||||
|
||||
**Recommendation:**
|
||||
- Already have optimized versions (portrait-600.webp at 31KB)
|
||||
- Ensure optimized versions are used in components
|
||||
- Remove unused original if all references use optimized versions
|
||||
|
||||
**Potential Savings:** ~1.1 MB per page using original
|
||||
|
||||
---
|
||||
|
||||
### 3. MEDIUM: Client Component Count
|
||||
|
||||
**Current State:** 13 client-side components detected
|
||||
|
||||
| Component | Needs Client? |
|
||||
|-----------|---------------|
|
||||
| Header.tsx | Yes (scroll, menu state) |
|
||||
| ContactForm.tsx | Yes (form state) |
|
||||
| LoginForm.tsx | Yes (form state) |
|
||||
| PortfolioCard.tsx | Review - possibly RSC |
|
||||
| PortfolioGrid.tsx | Review - possibly RSC |
|
||||
| NavLink.tsx | Review - possibly RSC |
|
||||
| LanguageSwitcher.tsx | Yes (dropdown state) |
|
||||
| ContactInfo.tsx | Review - possibly RSC |
|
||||
| Skills.tsx (sections) | Review - animations? |
|
||||
| Experience.tsx | Review - animations? |
|
||||
| Skills.tsx (about) | Review - animations? |
|
||||
| Hero.tsx (about) | Review - animations? |
|
||||
| DashboardContent.tsx | Yes (auth state) |
|
||||
|
||||
**Recommendation:**
|
||||
- Audit each client component for necessity
|
||||
- Convert static components to RSC where possible
|
||||
- Use `use client` only at the boundary where interactivity is needed
|
||||
|
||||
**Potential Impact:** Reduced JavaScript bundle, faster TTI
|
||||
|
||||
---
|
||||
|
||||
### 4. MEDIUM: Background SVG Animations
|
||||
|
||||
**File:** `/src/components/layout/GlobalBackground.tsx`
|
||||
|
||||
```typescript
|
||||
// Animated SVG lines with CSS animations
|
||||
<animate attributeName="y1" values="20%;80%;20%" dur="10s" repeatCount="indefinite" />
|
||||
```
|
||||
|
||||
**Current State:**
|
||||
- SVG-based animations (GPU-accelerated)
|
||||
- Low opacity (0.1-0.3)
|
||||
- Fixed positioning
|
||||
|
||||
**Assessment:** Generally performant, but:
|
||||
|
||||
**Recommendations:**
|
||||
- Consider `prefers-reduced-motion` media query
|
||||
- Lazy load on mobile devices
|
||||
- Test on low-end devices for jank
|
||||
|
||||
---
|
||||
|
||||
### 5. LOW: Missing Loading States
|
||||
|
||||
**Observation:** No skeleton loaders or loading states visible for dynamic content
|
||||
|
||||
**Recommendation:**
|
||||
- Add loading.tsx files for route segments
|
||||
- Use Suspense boundaries for data fetching
|
||||
- Implement skeleton UI for improved perceived performance
|
||||
|
||||
---
|
||||
|
||||
### 6. LOW: Consider Link Prefetching
|
||||
|
||||
**Current State:** Default Next.js prefetching (on hover)
|
||||
|
||||
**Recommendation:**
|
||||
- Verify prefetching is working correctly
|
||||
- Consider `prefetch={false}` for rarely-used links
|
||||
- Use `priority` prop on critical navigation links
|
||||
|
||||
---
|
||||
|
||||
## Performance Test Infrastructure
|
||||
|
||||
### Available Tests (`tests/e2e/performance.spec.ts`)
|
||||
|
||||
1. **Homepage Performance Tests**
|
||||
- Tests all 3 locales (de, en, sr)
|
||||
- Runs Lighthouse audits with 90% thresholds
|
||||
|
||||
2. **Critical Pages Performance**
|
||||
- Homepage, About, Portfolio, Contact
|
||||
- German locale only (optimization)
|
||||
|
||||
3. **Mobile Performance**
|
||||
- Pixel 5 emulation (375x812)
|
||||
- iPhone user agent
|
||||
|
||||
4. **Core Web Vitals Verification**
|
||||
- LCP threshold test
|
||||
- CLS measurement
|
||||
- Resource error monitoring
|
||||
|
||||
5. **Resource Loading Tests**
|
||||
- JavaScript bundle size (<500KB per chunk)
|
||||
- Image lazy loading verification
|
||||
- Modern image format detection
|
||||
|
||||
### Running Performance Tests
|
||||
|
||||
```bash
|
||||
# Run all performance tests
|
||||
npx playwright test tests/e2e/performance.spec.ts --project=chromium
|
||||
|
||||
# Run with HTML report
|
||||
npx playwright test tests/e2e/performance.spec.ts --reporter=html
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recommended Action Items
|
||||
|
||||
### Priority 1: Critical (Immediate)
|
||||
- [ ] Optimize hero-portrait.jpg (target: <500KB)
|
||||
- [ ] Run full Lighthouse audit once API access is available
|
||||
- [ ] Remove unused large image files
|
||||
|
||||
### Priority 2: High (This Sprint)
|
||||
- [ ] Audit client components for RSC conversion
|
||||
- [ ] Add loading.tsx for main route segments
|
||||
- [ ] Implement blur placeholder for hero image
|
||||
|
||||
### Priority 3: Medium (Next Sprint)
|
||||
- [ ] Add `prefers-reduced-motion` support
|
||||
- [ ] Review and optimize third-party scripts
|
||||
- [ ] Implement performance monitoring (web-vitals integration)
|
||||
|
||||
### Priority 4: Low (Backlog)
|
||||
- [ ] Bundle analysis and code splitting optimization
|
||||
- [ ] Edge caching configuration
|
||||
- [ ] Service worker implementation for offline support
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
### API Access Issue
|
||||
The PageSpeed Insights API was inaccessible during this audit (proxy/firewall blocking). For live metrics:
|
||||
|
||||
1. Use [PageSpeed Insights](https://pagespeed.web.dev/) directly in browser
|
||||
2. Run local Lighthouse via Chrome DevTools
|
||||
3. Use the Playwright performance tests locally
|
||||
|
||||
### Next Steps
|
||||
1. Resolve image optimization issues (Priority 1)
|
||||
2. Run Playwright performance tests with `npm run dev`
|
||||
3. Capture live metrics and update this baseline
|
||||
4. Track improvements over time
|
||||
|
||||
---
|
||||
|
||||
## Appendix: Configuration Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `next.config.ts` | Image optimization, headers, compiler options |
|
||||
| `playwright.config.ts` | E2E test configuration with Lighthouse ports |
|
||||
| `tests/e2e/performance.spec.ts` | Performance test suite |
|
||||
| `scripts/pagespeed-check.js` | PageSpeed API integration script |
|
||||
|
||||
---
|
||||
|
||||
*Generated by auto-claude performance audit*
|
||||
Reference in New Issue
Block a user