DocHub
Full codebase performance audit — DB queries, bundle/rendering, API routes

Performance Audit Findings

Full performance audit conducted March 4, 2026 across three areas: database queries, bundle/rendering, and API routes.

Critical Issues

1. Cart Page God Component

src/app/cart/page.tsx is 2,677 lines with 27 useState hooks. Every keystroke re-renders the entire page including all cart items, payment forms, and address inputs.

Impact: Severe input lag, excessive re-renders, poor mobile performance. Remediation: Split into sub-components (CartItems, PaymentSection, AddressCard, OrderSummary). Extract state into focused custom hooks.

2. Manager Dashboard Sequential API Calls

OrdersDashboardContent.tsx makes 8 sequential API calls (one per order status: pending, confirmed, preparing, ready, picked_up, delivered, cancelled, failed).

Impact: Dashboard load time ~2-4s on good connection. Each call waits for the previous. Remediation: Combine into single endpoint with status filter, or parallelize with Promise.all.

3. Auth Cost Per Request

Every authenticated request costs 2 DB roundtrips: JWT verification + user profile lookup from users table.

Impact: Adds ~50-100ms latency to every API call. Remediation: Cache user profile in JWT claims or use short-lived memory cache.

4. Image Optimization Disabled

next.config.ts has unoptimized: true on images. All images served at original resolution.

Impact: Menu pages load 5-10MB of images on mobile. Critical for Honduras bandwidth. Remediation: Remove unoptimized: true, configure Next.js image optimization with Cloudflare R2 loader.

High Issues

5. Order Detail Endpoint — Sequential Queries

Order detail API route makes 8-9 sequential DB queries: order, items, restaurant, customer, driver, address, payment, status history, ratings.

Impact: Single order detail takes 400-800ms. Remediation: Parallelize independent queries with Promise.all or use Supabase joins.

6. SWR Aggressive Revalidation

Global SWR config has revalidateOnFocus: true. Every tab switch triggers refetches across all cached endpoints.

Impact: Unnecessary network traffic, Supabase quota burn, UI flicker on tab return. Remediation: Disable revalidateOnFocus globally, use revalidateOnFocus selectively where freshness matters.

7. No Response Caching

Zero caching headers on any API response. Static data (restaurant info, menu items, categories) re-fetched on every request.

Impact: Redundant DB queries, higher Supabase usage, slower page loads. Remediation: Add Cache-Control headers for static/semi-static data (restaurants: 5min, menu: 2min).

8. Admin Drivers Endpoint — No Pagination

/api/admin/drivers returns all drivers with no pagination. Full table scan every request.

Impact: Grows linearly with driver count. Will degrade as platform scales. Remediation: Add limit/offset pagination, default 50 per page.

9. SELECT * Everywhere

All Supabase queries use select("*") instead of specific columns. Fetches all columns including unused ones.

Impact: Larger payloads, slower serialization, unnecessary data transfer. Remediation: Replace with specific column selections per query.

Optimizations Implemented (March 4)

Completed Fixes

Fix Description Files
Firebase dead code removal Deleted unused firebase.ts and converters.ts 2 files deleted
CartContext memoization Wrapped 10 handlers in useCallback, context value in useMemo CartContext.tsx
Visibility-aware polling Created useVisibilityAwareInterval hook — pauses intervals when tab backgrounded 6 components updated
Blob URL memory leaks Restaurant/menu image uploads now revoke old blob URLs ManagerConsole.tsx
Rogue local fetcher Replaced raw fetch() with shared apiClient fetcher restaurants/page.tsx

useVisibilityAwareInterval Applied To

  • Header.tsx (30s active order badge)
  • admin/orders/page.tsx (15s orders)
  • OrdersDashboardContent.tsx (15s orders)
  • ManagerConsole.tsx (15-30s auto-refresh)
  • ManagerNotificationListener.tsx (5s localStorage + 60s orders)
  • orders/page.tsx (30s polling)