[Critical] Add pagination to feature endpoints to prevent performance issues
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 5
- Forks
- 17
- Avg merge
- 3h 45m
- Merged PRs (30d)
- 220
Description
Problem
Currently, GET /api/features/[featureId] returns the entire feature with ALL phases and ALL tasks in a single response. This creates several issues:
- Unbounded response size: A feature with 200 tasks results in a multi-MB JSON response
- Browser performance: React rendering hundreds of task rows can freeze the UI
- Network timeouts: Large responses timeout on slow connections
- Scale ceiling: System will break at ~200 tasks per feature
Current Implementation
API Route: /src/app/api/features/[featureId]/route.ts
// Returns everything at once
const feature = await getFeature(featureId, userId);
// Includes: feature.phases[].tasks[] - unbounded arrays
Type Definition: /src/types/roadmap.tsx
export interface FeatureDetail {
phases: PhaseWithTasks[]; // Each phase has tasks: TicketListItem[]
// No pagination metadata
}
Frontend: /src/app/w/[slug]/roadmap/[featureId]/page.tsx
- Fetches entire feature on mount
- Passes all tasks to TicketsList component
- No virtualization or windowing
Proposed Solution
Lazy-load tasks when user navigates to Tasks tab
Phase 1: Separate endpoints
GET /api/features/[featureId] // Feature + phases metadata only (no tasks)
GET /api/features/[featureId]/tasks?page=1&limit=50 // Paginated tasks
Phase 2: Frontend changes
- Feature detail page fetches feature without tasks
- Tasks tab triggers separate fetch when user clicks "Tasks"
- Add virtual scrolling with react-window for task list rendering
Phase 3: Backend optimization
- Add cursor-based pagination for efficient queries
- Return pagination metadata:
{ data: [], pagination: { total, page, limit, hasMore } }
Alternative: Query parameter approach
GET /api/features/[featureId]?includeTasks=false // Default: exclude tasks
GET /api/features/[featureId]?includeTasks=true&tasksPage=1&tasksLimit=50
Success Criteria
- Feature with 500 tasks loads in <2 seconds
- Browser doesn't freeze when rendering task list
- API response size stays under 1MB regardless of task count
- Tasks are fetched only when user navigates to Tasks tab
Code References
/src/app/api/features/[featureId]/route.ts- API route handler/src/services/roadmap/features.ts- getFeature service function/src/types/roadmap.tsx- FeatureDetail type (lines 620-640)/src/components/features/TicketsList/index.tsx- Frontend component that renders tasks
Effort Estimate
2-3 weeks
- Backend API changes: 3-4 days
- Frontend refactoring: 4-5 days
- Virtual scrolling implementation: 2-3 days
- Testing and optimization: 3-4 days
Priority
Critical - This will become a blocker as features grow beyond 50-100 tasks.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/app/api/features/[featureId]/route.ts and src/services/roadmap/features.ts to trace how phases and tasks are loaded, then review FeatureDetail in src/types/roadmap.tsx and TicketsList in src/components/features/TicketsList/index.tsx. Define the endpoint and loading changes needed for lazy, paginated tasks and verify the success criteria: bounded responses, no UI freeze, and tasks fetched only on the Tasks tab.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- api, frontend, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100