When I first built my React + Laravel application, everything worked fine—until the data started growing.
Pages that used to load instantly began taking seconds. Then even longer.
At first, I thought it was a frontend issue. Maybe React was re-rendering too much. Maybe my components weren’t optimized.
I was wrong.
The real problem was happening in the backend—and it had a name: the N+1 query problem.
The Problem I Didn’t See at First
Let’s say I had something like this in my Laravel backend:
- A list of students
- Each student has marks
- Each mark belongs to a subject
Simple, right?
But here’s what actually happened when I fetched data:
1 query to get students
Then N queries to get each student's related data
So if I had 100 students, I was running:
👉 101 queries
That’s the N+1 problem.
And it destroyed performance.
How I Discovered It
I started debugging the backend and noticed something strange:
- The API response time was slow
- Database queries were increasing with data size
So I used Laravel debugging tools and logs.
That’s when I saw it clearly:
👉 Queries were being executed inside loops
That’s the moment it clicked.
The Fix: Eager Loading
Laravel already has a solution for this: Eager Loading
Instead of fetching related data one-by-one, I loaded everything in a single query.
Before (Bad)
$students = Student::all();
foreach ($students as $student) {
echo $student->marks; // triggers query every time
}
After (Good)
$students = Student::with('marks')->get();
Now:
- Only 2 queries total
- No matter how many students
Massive improvement.
Going Deeper: Nested Relationships
My case wasn’t that simple.
I had deeper relationships like:
- students → marks → subjects
So I used nested eager loading:
$students = Student::with('marks.subject')->get();
Now everything loads efficiently in minimal queries.
Optimizing the API Response
Fixing queries wasn’t enough.
I also improved how data was sent to React.
What I changed:
- Removed unnecessary fields
- Used API Resources (Transformers)
- Sent only what the UI actually needs
return StudentResource::collection($students);
This reduced payload size and improved speed.
React Side Optimization
After fixing Laravel, I improved React too.
1. Avoid Unnecessary Re-renders
I used:
useMemouseCallback- Proper state structure
2. Lazy Loading Components
const Dashboard = React.lazy(() => import('./Dashboard'));
This reduced initial load time.
3. Efficient Data Fetching
- Avoided duplicate API calls
- Cached results when possible
The Result
After all optimizations:
- Page load time dropped significantly
- API became faster and more scalable
- UI felt instant even with large data
What used to feel slow and heavy became smooth and responsive.
What I Learned
This experience taught me something important:
Performance problems are often not where you think they are.
I spent time looking at React—but the real issue was in the database.
Key Takeaways
- Always watch for N+1 queries in backend systems
- Use Eager Loading in Laravel (
with()) - Optimize API responses, not just queries
- Frontend performance depends on backend efficiency
Final Thoughts
Fixing the N+1 query problem completely changed how I think about building applications.
Now, whenever I design a feature, I ask:
👉 How many queries will this run?
Because performance isn’t just about code—it’s about how systems interact.
And once you fix the root problem, everything becomes faster.
Top comments (0)