Skip to main content
Version: 1.0.0
Last Updated: 2025-12-31
Target Audience: Developers and AI agents (GitHub Copilot, Cursor, general AI assistants)
Comprehensive guide for performance optimization in the Encore OS Platform, covering debugging workflows, bundle optimization, query optimization, image optimization, lazy loading, caching, and performance targets.

AI Agent Context

Key Patterns for AI:
  • Always use React.lazy() for route components (required for code splitting)
  • Always configure QueryClient with staleTime and gcTime (prevents unnecessary refetches)
  • Always select only needed columns in database queries (never SELECT *)
  • Always use skeleton loaders for loading states (never return null)
  • Always optimize images (WebP format, lazy loading, proper sizing)
Common Mistakes to Avoid:
  • Direct imports for route components (must use React.lazy())
  • Missing QueryClient configuration (causes excessive API calls)
  • Using SELECT * in queries (fetches unnecessary data)
  • Returning null for loading states (causes layout shifts)
  • Not optimizing images (slows page loads)

Quick Reference


Performance Debugging Workflow

1. Measure Current Performance

Lighthouse Audit:
Bundle Analysis:
Network Analysis:
  • Open Chrome DevTools → Network tab
  • Check for large files, slow requests
  • Look for duplicate requests

2. Identify Bottlenecks

Common Issues:
  • Large initial bundle (>500KB)
  • Slow queries (>1s)
  • Unoptimized images
  • Missing code splitting
  • Excessive re-renders

3. Apply Optimizations

Follow optimization patterns below based on identified issues.

4. Verify Improvements

  • Re-run Lighthouse audit
  • Compare bundle sizes
  • Test on slow 3G connection
  • Verify performance targets met

Bundle Size Optimization

Route Code Splitting (REQUIRED)

✅ CORRECT: Use React.lazy() for all routes
❌ WRONG: Direct imports for routes

Tree-Shakeable Imports

✅ CORRECT: Import only what you need
❌ WRONG: Import entire libraries

Manual Chunk Splitting (Vite 8 / Rolldown)

Location: vite.config.ts Vite 8 bundles with Rolldown. The old Rollup object form output.manualChunks is removed; use build.rolldownOptions.output.codeSplitting.groups with test regexes and priority (see Vite migration guide). Pattern (illustrative — match real vite.config.ts for full vendor split list):
Benefits:
  • Better caching (vendor chunks change less frequently)
  • Parallel loading
  • Smaller initial bundle

Query Optimization

Select Only Needed Columns

✅ CORRECT: Select specific columns
❌ WRONG: Select all columns

Use Pagination

✅ CORRECT: Limit results

QueryClient Configuration (REQUIRED)

Location: src/App.tsx
Benefits:
  • Reduces API calls (cached for 5 minutes)
  • Faster UI (instant data from cache)
  • Better offline experience

Optimize Query Keys

✅ CORRECT: Specific query keys
❌ WRONG: Too broad query keys

Image Optimization

Use Modern Formats

✅ CORRECT: WebP format
❌ WRONG: Large PNG/JPG

Lazy Loading

✅ CORRECT: Lazy load images

Responsive Images

✅ CORRECT: Responsive srcset

Image Sizing

  • Icons: 16-32px (SVG preferred)
  • Thumbnails: 64-128px
  • Hero images: Max 1920px width
  • Use appropriate formats: SVG for icons, WebP for photos

Lazy Loading Patterns

Route Lazy Loading (REQUIRED)

Pattern:

Component Lazy Loading

For heavy components:

Dynamic Imports

For conditional features:

Caching Strategies

QueryClient Caching

Automatic caching with TanStack Query:

Manual Cache Invalidation

Browser Caching

Static assets (handled by Vite):
  • Files with content hashes are cached long-term
  • Changed files get new hashes (cache busting)
API responses:
  • Use QueryClient caching (not browser cache)
  • Configure staleTime appropriately

Performance Targets

Lighthouse Scores

Targets:
  • Performance: 85+
  • Accessibility: 90+
  • Best Practices: 90+
  • SEO: 90+
  • PWA: 90+

Core Web Vitals

Targets:
  • First Contentful Paint (FCP): < 2s
  • Largest Contentful Paint (LCP): < 2.5s
  • Cumulative Layout Shift (CLS): < 0.1
  • Time to Interactive (TTI): < 3.5s on 3G
  • Total Blocking Time (TBT): < 300ms

Bundle Size Targets

  • Initial bundle: < 200KB (gzipped)
  • Route chunks: < 100KB each (gzipped)
  • Vendor chunks: < 300KB total (gzipped)

Performance Monitoring

Chrome DevTools

Performance Tab:
  1. Open DevTools → Performance
  2. Click Record
  3. Interact with app
  4. Stop recording
  5. Analyze flame chart
Network Tab:
  • Check file sizes
  • Look for slow requests
  • Identify duplicate requests

Bundle Analysis

Real User Monitoring

Consider adding:
  • Web Vitals tracking
  • Error tracking (Sentry)
  • Performance API monitoring

Common Performance Issues

Issue: Large Initial Bundle

Symptoms: Slow initial page load, large bundle size Solutions:
  1. Verify all routes use React.lazy()
  2. Check for direct route imports
  3. Analyze bundle with vite-bundle-visualizer
  4. Split vendor chunks in vite.config.ts

Issue: Slow Queries

Symptoms: Queries take > 1 second Solutions:
  1. Select only needed columns (not *)
  2. Add pagination (.range())
  3. Add indexes for frequently queried columns
  4. Use QueryClient caching

Issue: Excessive Re-renders

Symptoms: UI feels sluggish, many re-renders Solutions:
  1. Use React.memo() for expensive components
  2. Use useMemo() for expensive calculations
  3. Use useCallback() for stable function references
  4. Check for unnecessary state updates

Issue: Images Loading Slowly

Symptoms: Images take time to appear Solutions:
  1. Convert to WebP format
  2. Add loading="lazy" attribute
  3. Use responsive images with srcset
  4. Optimize image sizes

Standards

Development Guides

Performance Resources


Maintained By: Platform Foundation Team