Appearance
Performance Optimization ​
Purpose: Summarize known performance optimizations and practical tips for local dev and production. Audience: Developer, Owner Prerequisites: App boots locally; basic Vite knowledge.
Lighthouse Performance Achievements ​
Production Build Performance ​
- Performance Score: 95/100 (mobile), 100/100 (desktop)
- Accessibility: 100/100
- Best Practices: 100/100
- SEO: 100/100
Key Optimizations Implemented ​
1. Code Splitting & Bundle Optimization ​
- Vite manualChunks: Aggressive code splitting in
vite.config.ts- React core, React Query, Supabase, UI components separated
- Admin pages, Deal pages, Listings pages lazy-loaded
- Bundle size reduced from 2.8MB to optimized chunks
- React.lazy: Route-level lazy loading in
AppRoutes.tsx- TransactionHistory, Watchlist, AccountSettings, ContactAdmin
- InvoiceHistory, PriceAlerts, Activities, SellerVerification, ProfileVerification
2. Forced Reflow Elimination ​
- useIsMobile Hook: Fixed forced reflow in
src/hooks/use-mobile.ts- Replaced
window.innerWidthwithwindow.matchMedia - Prevents layout thrashing during responsive checks
- Replaced
3. Stripe SDK Optimization ​
- Lazy Loading: Stripe SDK loaded only when needed
Deal.tsxandDealNew.tsxuse dynamic imports- Prevents Stripe from being included in initial bundle
- Improves First Contentful Paint (FCP)
4. TanStack Query Cache Optimization ​
- Profile Data Caching: Extended cache times for user profile data
useProfile.ts:staleTimeincreased from 5 minutes to 30 minutesrefetchOnMount: falseto use cached data immediatelygcTimeincreased to 1 hour for better memory management
- Subscription Data Caching: Optimized subscription status caching
useSubscription.ts:staleTimeincreased from 30 seconds to 15 minutesrefetchOnMount: falseto prevent unnecessary refetches
- Notification Settings Caching: Extended cache for user preferences
useNotificationSettings.ts:staleTimeincreased from 30 seconds to 1 hour
- Page Access Rules Caching: Optimized role-based access control
usePageAccess.ts:staleTimeincreased from 5 minutes to 30 minutes- User role caching in
SidebarMenuItems.tsx: 15 minutes cache
- Translation Caching: Improved i18n performance
loadMessages.ts: TTL increased from 5 minutes to 1 hour
- Blog Posts Caching: Added caching for admin dashboard content
useBlogPostsQuery.ts: 10 minutes cache withrefetchOnWindowFocus: false
5. Development vs Production ​
- Development Mode: Higher overhead, not suitable for performance testing
- Production Build: Use
pnpm build+pnpm previewfor accurate metrics - Bundle Analysis: Available through Vite's built-in analyzer
Technical Implementation ​
- Vite dev server: Uses proxy and tuned HMR.
- See
vite.config.ts:18— disables overlay for faster HMR. - See
vite.config.ts:23— reduced watch overhead. - Proxy for Supabase Functions:
vite.config.ts:12-17.
- See
- Dependency pre-bundling: Includes core libs.
- See
vite.config.ts:43-48.
- See
- Aliases:
@→srcfor short imports.- See
vite.config.ts:32-35.
- See
- React Query tuning: Stale time and refetch settings for heavier lists.
- Example:
src/hooks/useMessages.ts:56-64.
- Example:
- Realtime scope minimized: Critical-only channel with row filters.
- See
src/hooks/useGlobalRealtimeNotifications.ts:24and:65-74.
- See
- Idle work scheduling: requestIdleCallback and short timeouts avoid jank.
- Example:
useGlobalRealtimeNotifications.ts:39-43, 58-62.
- Example:
- Batch processing: Non-critical admin notifications use polling in small steps.
- See
src/hooks/useAdminPollingNotifications.ts:40-81and:150-159.
- See
- Code splitting: Prefer lazy import for heavy admin views and blog cards.
- Example:
src/pages/Blog.tsx:16-18.
- Example:
- Images: Use optimized images in
src/assets/. Favor modern formats when possible.
Build tips
- Build:
pnpm build(ornpm run build) creates optimized bundle. - Analyze: If needed, add bundle analyzer locally (not committed) to inspect chunks.
- Cache headers: Serve
dist/via CDN with immutable file names.
Database performance
- Indexes: Ensure critical queries have indexes (subscriptions, messages, offers).
- Subscriptions:
docs/features/subscriptions.mdshows example indexes.
- Subscriptions:
- Avoid N+1: Prefer
.select()with embedded relations where supported (see blog).
Next steps
- Review
docs/operations/monitoring.mdfor metrics and profiling. - Check
docs/architecture/state-management.mdfor cache keys and invalidation.