Files
Portfolio/OPTIMIZATION_RECOMMENDATIONS.md
T
damjan_savicandClaude Opus 4.5 ac4b85bbc1 auto-claude: subtask-8-4 - Create optimization recommendations document
Create comprehensive OPTIMIZATION_RECOMMENDATIONS.md based on audit results:
- Priority 1: Critical optimizations (image compression, production verification)
- Priority 2: High-impact (client component audit, loading states, blur placeholders)
- Priority 3: Medium-impact (reduced motion, third-party scripts, font loading, DB indexes)
- Priority 4: Strategic (PWA, bundle analysis, edge caching, CDN optimization)
- Implementation roadmap with weekly/monthly milestones
- Success metrics and targets

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 02:34:17 +01:00

15 KiB

Optimization Recommendations Report

Project: damjan-savic.com Portfolio Website Date: 2026-01-25 Prepared by: auto-claude Status: Final Recommendations (Post-Audit)


Executive Summary

This document provides comprehensive optimization recommendations based on the completed SEO audit, performance testing, and implementation work. The recommendations are organized by priority and impact, covering areas from quick wins to strategic long-term improvements.

Current State

Category Status Score
SEO Complete 100%
Accessibility Passing 92-100%
Best Practices Passing 100%
Performance (Dev) ⚠️ Expected Low 47-69%*
Performance (Prod) 📋 To Verify Expected 85-95%

*Development mode scores are lower due to unminified code, HMR overhead, and source maps.


Priority 1: Critical Optimizations (Immediate Action)

1.1 Image Optimization - Hero Portrait

Issue: The hero portrait image is 2.9 MB, significantly impacting LCP and overall page weight.

File: /public/hero-portrait.jpg Current Size: 2,957,516 bytes (~2.9 MB) Target Size: < 500 KB (80-85% reduction)

Recommendations:

# Option 1: Manual compression with ImageMagick
magick hero-portrait.jpg -quality 82 -strip hero-portrait-optimized.jpg

# Option 2: Convert to WebP format
magick hero-portrait.jpg -quality 80 hero-portrait.webp

# Option 3: Use AVIF for maximum compression
magick hero-portrait.jpg -quality 60 hero-portrait.avif

Implementation Steps:

  1. Compress original to <500KB maintaining visual quality
  2. Generate responsive variants (300, 600, 900, 1200px widths)
  3. Create AVIF and WebP versions for modern browser support
  4. Update Next.js Image component with blur placeholder
  5. Add fetchpriority="high" for LCP optimization

Expected Improvement:

  • LCP: -1.5 to 2.0 seconds
  • Page weight: -2.0 to 2.5 MB
  • Mobile performance: +15-25 points

1.2 Unused Large Images Cleanup

Issue: Multiple large image files may not be referenced in production.

Files to Audit:

File Size Status
/public/portrait.jpg 1.2 MB Verify usage
/public/hero-portrait.jpg 2.9 MB Needs optimization

Recommendation:

  1. Run image usage audit:
    grep -r "portrait.jpg" src/ --include="*.tsx" --include="*.ts"
    grep -r "hero-portrait.jpg" src/ --include="*.tsx" --include="*.ts"
    
  2. Replace references with optimized versions
  3. Remove unused originals from /public

1.3 Production Performance Verification

Issue: PageSpeed API was blocked during testing. Production verification required.

Action Required:

  1. Visit PageSpeed Insights

  2. Test all main URLs:

    • https://www.damjan-savic.com/de
    • https://www.damjan-savic.com/en
    • https://www.damjan-savic.com/sr
    • https://www.damjan-savic.com/de/about
    • https://www.damjan-savic.com/de/portfolio
    • https://www.damjan-savic.com/de/contact
  3. Document scores for Desktop and Mobile

  4. If any score < 90%, implement specific recommendations from report


Priority 2: High-Impact Optimizations (This Sprint)

2.1 Client Component Audit

Issue: 13 client-side components identified. Some may be convertible to React Server Components (RSC).

Current Client Components:

Component Client Necessary? Recommendation
Header.tsx Yes Scroll/menu state
ContactForm.tsx Yes Form state
LoginForm.tsx Yes Form state
PortfolioCard.tsx 🔍 Review Consider RSC
PortfolioGrid.tsx 🔍 Review Consider RSC
NavLink.tsx 🔍 Review Consider RSC
ContactInfo.tsx 🔍 Review Consider RSC
Skills.tsx 🔍 Review Animation-dependent
Experience.tsx 🔍 Review Animation-dependent
Hero.tsx (about) 🔍 Review Animation-dependent
LanguageSwitcher.tsx Yes Dropdown state
DashboardContent.tsx Yes Auth state
Chatbot.tsx Yes Interactive

Recommendation:

  1. For animation-dependent components, consider:

    • Static initial render as RSC
    • Minimal client wrapper for animations only
    • Use CSS animations where possible (GPU-accelerated)
  2. Conversion pattern:

    // Before: Full client component
    'use client';
    export function PortfolioCard({ project }) {
      return <div>{/* all content */}</div>;
    }
    
    // After: Server component with client wrapper
    export function PortfolioCard({ project }) {
      return (
        <PortfolioCardWrapper>
          <div>{/* static content */}</div>
        </PortfolioCardWrapper>
      );
    }
    

Expected Improvement:

  • JavaScript bundle: -50-150 KB
  • TTI (Time to Interactive): -200-500ms

2.2 Loading States and Suspense Boundaries

Issue: No loading.tsx files detected for route segments.

Recommendation: Create loading states for improved perceived performance:

// src/app/[locale]/loading.tsx
export default function Loading() {
  return (
    <div className="animate-pulse">
      <div className="h-8 bg-gray-200 rounded w-1/3 mb-4" />
      <div className="h-4 bg-gray-200 rounded w-full mb-2" />
      <div className="h-4 bg-gray-200 rounded w-2/3" />
    </div>
  );
}

// src/app/[locale]/portfolio/loading.tsx
export default function PortfolioLoading() {
  return (
    <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
      {[...Array(6)].map((_, i) => (
        <div key={i} className="animate-pulse rounded-lg bg-gray-200 h-64" />
      ))}
    </div>
  );
}

Files to Create:

  • src/app/[locale]/loading.tsx
  • src/app/[locale]/about/loading.tsx
  • src/app/[locale]/portfolio/loading.tsx
  • src/app/[locale]/contact/loading.tsx

2.3 Blur Placeholder for Hero Image

Recommendation: Add blur placeholder for improved perceived LCP:

// In Hero component
import Image from 'next/image';

// Generate blur data URL (base64 encoded tiny version)
const heroBlurDataURL = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..."; // Generate with plaiceholder

<Image
  src="/hero-portrait.jpg"
  alt="Damjan Savić"
  fill
  priority
  placeholder="blur"
  blurDataURL={heroBlurDataURL}
  sizes="(max-width: 768px) 100vw, 50vw"
/>

Implementation:

  1. Install plaiceholder: pnpm add plaiceholder sharp
  2. Generate blur data URLs at build time
  3. Update Image components with placeholder prop

Priority 3: Medium-Impact Optimizations (Next Sprint)

3.1 Reduced Motion Support

Issue: Background SVG animations may cause issues for users with vestibular disorders.

File: /src/components/layout/GlobalBackground.tsx

Recommendation:

// Add media query support
const GlobalBackground = () => {
  const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');

  if (prefersReducedMotion) {
    return <StaticBackground />;
  }

  return <AnimatedBackground />;
};

// Or use CSS-only approach
<style>
  @media (prefers-reduced-motion: reduce) {
    .animated-bg * {
      animation: none !important;
      transition: none !important;
    }
  }
</style>

3.2 Third-Party Script Optimization

Issue: Google Analytics may block rendering if not loaded properly.

Current Implementation: Review needed

Recommendations:

  1. Use Partytown for off-main-thread execution:

    pnpm add @builder.io/partytown
    
  2. Defer non-critical scripts:

    // In layout.tsx or Script component
    import Script from 'next/script';
    
    <Script
      src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
      strategy="afterInteractive"
    />
    
  3. Consider self-hosting analytics for better control:

    • Plausible Analytics (privacy-focused, <1KB)
    • Umami Analytics (self-hosted option)

Expected Improvement:

  • TBT (Total Blocking Time): -50-100ms
  • FCP: -100-200ms

3.3 Font Loading Optimization

Current State: Font swap implemented (good baseline)

Further Optimizations:

  1. Subset fonts to required characters only:

    /* Only load Latin subset */
    @font-face {
      font-family: 'Inter';
      src: url('/fonts/inter-latin.woff2') format('woff2');
      unicode-range: U+0000-00FF, U+0131, U+0152-0153;
    }
    
  2. Preload critical font files:

    <link
      rel="preload"
      href="/fonts/inter-var.woff2"
      as="font"
      type="font/woff2"
      crossorigin="anonymous"
    />
    
  3. Consider variable fonts to reduce total file count


3.4 Database Indexing for Chat

Issue: Chat queries may become slow with scale.

Current Indexes:

  • idx_chat_messages_session on session_id

Recommended Additional Indexes:

-- For visitor lookup (session continuity)
CREATE INDEX idx_chat_sessions_visitor
ON chat_sessions(visitor_id);

-- For recent sessions (cleanup queries)
CREATE INDEX idx_chat_sessions_created
ON chat_sessions(created_at DESC);

-- For message ordering
CREATE INDEX idx_chat_messages_created
ON chat_messages(session_id, created_at);

-- Composite index for efficient session + message retrieval
CREATE INDEX idx_chat_messages_session_created
ON chat_messages(session_id, created_at DESC);

Priority 4: Strategic Improvements (Backlog)

4.1 Progressive Web App (PWA) Implementation

Benefit: Offline support, app-like experience, improved mobile engagement

Implementation:

  1. Create service worker:

    // src/app/sw.ts
    import { precacheAndRoute } from 'workbox-precaching';
    
    precacheAndRoute(self.__WB_MANIFEST);
    
  2. Add manifest:

    // public/manifest.json
    {
      "name": "Damjan Savić - Portfolio",
      "short_name": "DS Portfolio",
      "start_url": "/",
      "display": "standalone",
      "background_color": "#0a0a0a",
      "theme_color": "#3b82f6",
      "icons": [
        { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
        { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
      ]
    }
    
  3. Configure next.config.ts for PWA:

    pnpm add next-pwa
    

4.2 Bundle Analysis and Code Splitting

Recommendation:

  1. Analyze current bundle:

    pnpm add @next/bundle-analyzer
    
    # In next.config.ts
    const withBundleAnalyzer = require('@next/bundle-analyzer')({
      enabled: process.env.ANALYZE === 'true',
    });
    
    module.exports = withBundleAnalyzer(nextConfig);
    
    # Run analysis
    ANALYZE=true npm run build
    
  2. Identify large dependencies for lazy loading:

    • framer-motion (if not needed on all pages)
    • lucide-react icons (ensure tree-shaking)
    • openai SDK (server-only)
  3. Implement dynamic imports for heavy components:

    const Chatbot = dynamic(() => import('@/components/chat/Chatbot'), {
      loading: () => <ChatbotSkeleton />,
      ssr: false,
    });
    

4.3 Edge Caching Strategy

Current State: Static assets cached for 1 year (good)

Additional Recommendations:

  1. Configure Vercel Edge Config for dynamic content:

    // Cache API responses at edge
    export const runtime = 'edge';
    export const revalidate = 60; // 1 minute
    
  2. Implement stale-while-revalidate for blog posts:

    export async function generateStaticParams() {
      return blogPosts.map((post) => ({ slug: post.slug }));
    }
    
    export const dynamicParams = true;
    export const revalidate = 3600; // 1 hour
    
  3. Use ISR (Incremental Static Regeneration) for portfolio projects


4.4 Content Delivery Optimization

Recommendations:

  1. Enable Brotli compression (Vercel default)
  2. Use HTTP/2 Push for critical resources
  3. Implement preload hints:
    <link rel="preload" href="/fonts/inter.woff2" as="font" crossorigin />
    <link rel="preload" href="/hero-portrait.avif" as="image" />
    <link rel="preconnect" href="https://api.deepseek.com" />
    

Monitoring and Continuous Improvement

Tool Purpose Priority
Google Search Console SEO monitoring, indexing issues Required
Google Analytics 4 Traffic, user behavior Already Implemented
Web Vitals Dashboard CWV tracking over time Recommended
Vercel Analytics Performance insights Recommended
Lighthouse CI Automated performance testing 🔄 Consider

Automated Testing Pipeline

# .github/workflows/lighthouse.yml
name: Lighthouse CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm run build
      - run: npm start &
      - run: npx lighthouse-ci autorun

Implementation Roadmap

Week 1 (Immediate)

  • Optimize hero-portrait.jpg to <500KB
  • Verify production PageSpeed scores via web interface
  • Remove unused large images

Week 2-3 (High Priority)

  • Audit and convert client components to RSC where possible
  • Add loading.tsx files for all route segments
  • Implement blur placeholders for hero images

Month 1 (Medium Priority)

  • Add prefers-reduced-motion support
  • Optimize third-party script loading
  • Add database indexes for chat tables

Quarter 1 (Strategic)

  • Implement PWA with service worker
  • Run bundle analysis and optimize
  • Set up Lighthouse CI in GitHub Actions
  • Configure edge caching for dynamic content

Success Metrics

Metric Current Target Measurement
PageSpeed Performance (Desktop) 47-69%* ≥90% PageSpeed Insights
PageSpeed Performance (Mobile) 40-60%* ≥90% PageSpeed Insights
LCP ~3-5s* <2.5s Web Vitals
INP Unknown <200ms Web Vitals
CLS <0.25 <0.1 Web Vitals
Total Page Weight ~4-5MB <1.5MB Network Panel
JavaScript Bundle ~1.3MB* <500KB Bundle Analyzer

*Development mode estimates; production expected to be significantly better.


References

Documentation

  • PERFORMANCE_BASELINE.md - Initial performance analysis
  • PAGESPEED_VERIFICATION_REPORT.md - PageSpeed test results
  • SEO_FINAL_STATUS_COMPLETE.md - SEO implementation status
  • SEO_AUDIT_REPORT.md - Detailed SEO findings

Report generated by auto-claude as part of the SEO Optimization, Performance Testing & Chatbot Integration project.