53 lines
2.4 KiB
Markdown
53 lines
2.4 KiB
Markdown
# Performance Awareness
|
|
|
|
## Frontend Performance
|
|
|
|
### Bundle Size
|
|
- Avoid importing entire libraries — use tree-shakable imports
|
|
- Dynamic `import()` for heavy components (modals, editors, charts)
|
|
- Check: `@next/bundle-analyzer` if bundle grows unexpectedly
|
|
- Never import server-only code in client components
|
|
|
|
### Rendering
|
|
- Memoize expensive computations with `useMemo`/`useCallback` only when profiling shows a bottleneck — not preemptively
|
|
- Avoid prop drilling through many layers — use stores or context at the right level
|
|
- Keep `useEffect` dependency arrays tight — stale closures are better caught by the TypeScript hook than by runtime bugs
|
|
|
|
### Images & Media
|
|
- Always use `next/image` with explicit width/height or `fill` + `sizes`
|
|
- Lazy-load below-the-fold images (default in next/image)
|
|
- Video thumbnails: use S3 presigned URLs with appropriate cache headers
|
|
|
|
## Backend Performance
|
|
|
|
### Database Queries
|
|
- Always use `.options(selectinload(...))` or `.options(joinedload(...))` for related data — N+1 queries are the #1 backend perf killer
|
|
- Add `.limit()` to any query that could return unbounded results
|
|
- Use `EXPLAIN ANALYZE` (via DB Architect agent or MCP postgres) before optimizing — measure, don't guess
|
|
- Index foreign keys and columns used in WHERE/ORDER BY
|
|
|
|
### Async Patterns
|
|
- Never use `time.sleep()` — use `asyncio.sleep()` in async code
|
|
- Never call sync I/O (file reads, HTTP requests) in async endpoints — use `run_in_executor` or async libraries
|
|
- Dramatiq tasks are sync — that's fine, they run in worker processes
|
|
|
|
### Caching
|
|
- Use Redis for frequently-accessed, rarely-changed data (user settings, project metadata)
|
|
- Cache at service layer, not repository layer
|
|
- Always set TTL — no unbounded caches
|
|
|
|
## Remotion Performance
|
|
|
|
- Keep composition prop data minimal — don't pass full transcription objects, pass pre-processed caption arrays
|
|
- Use `delayRender`/`continueRender` for async data loading in compositions
|
|
- Prefer `interpolate()` over `spring()` for simple animations — springs are heavier
|
|
|
|
## Agent Model Selection
|
|
|
|
When dispatching subagents, consider token cost:
|
|
- **Sonnet** (default): Standard development work, code generation, reviews
|
|
- **Haiku**: Lightweight lookups, simple code transformations, data extraction
|
|
- **Opus**: Complex architectural decisions, deep analysis, ambiguous requirements
|
|
|
|
Use `model: "haiku"` parameter on Agent tool for cheap, focused tasks.
|