You run Lighthouse.
Performance: 95.
Everything looks great.
Then you actually use the application.
You click a button.
Wait.
Open a dashboard.
Wait.
Submit a form.
Wait again.
Technically, your website is “fast.”
But it doesn't feel fast.
This is something that can be confusing when optimizing modern web applications, especially with frameworks like Next.js.
The reason is simple:
Page speed and perceived performance aren't exactly the same thing.
Lighthouse doesn't experience your app like a user
Performance tools are incredibly useful.
They can identify problems with things like:
Largest Contentful Paint
Cumulative Layout Shift
blocking resources
image optimization
JavaScript execution
caching
But users don't care about performance scores.
They care about what happens after they click something.
A page can load extremely quickly and still have interactions that feel slow.
The first load isn't the entire experience
Imagine a dashboard.
The initial page loads in 800ms.
Great.
Then the user clicks Orders.
Your application sends an API request.
The API queries the database.
The database takes 600ms.
The server processes the response.
The browser receives it.
React renders the result.
Suddenly the user has been waiting more than a second.
Your homepage performance score didn't tell you much about that experience.
For applications, you have to think about the entire chain:
User → Browser → Server → Database → Server → Browser → UI
Every step can introduce latency.
Loading states change how speed feels
Consider two applications.
Application A:
User clicks a button.
Nothing happens for 900ms.
Then the new page appears.
Application B:
User clicks a button.
The interface immediately shows that something is happening.
The new page appears after the same 900ms.
Technically, both took the same amount of time.
But Application B usually feels faster.
That's why loading states, skeletons, optimistic updates, and immediate visual feedback matter.
Performance isn't only about reducing milliseconds.
It's also about communicating what's happening during those milliseconds.
Don't fetch everything immediately
Another common problem is loading information that the user hasn't requested yet.
Imagine a dashboard containing:
profile information
notifications
messages
analytics
recent transactions
recommendations
It's tempting to fetch everything when the dashboard opens.
But does the user need everything immediately?
Probably not.
Prioritize what is visible and important.
Load secondary information later when appropriate.
A smaller initial workload can make the interface feel significantly more responsive.
Database latency becomes frontend latency
Frontend developers sometimes optimize everything in the browser while ignoring what happens behind the API.
Suppose your API request takes 1.5 seconds.
Removing 30ms of JavaScript isn't going to fix the experience.
Look at the entire request.
Maybe you're making multiple database queries when one would work.
Maybe a column isn't indexed.
Maybe you're repeatedly requesting information that could be cached.
Maybe your application server and database are geographically far apart.
Maybe you're performing expensive operations synchronously.
The bottleneck might have nothing to do with React.
Geography matters more than you think
If your server is in Europe and your user is also in Europe, network latency may barely be noticeable.
Now put the user in California.
Every request has to travel significantly farther.
And applications rarely make just one request.
A small amount of additional latency multiplied across many sequential operations can create a noticeably slower experience.
This is where CDNs, caching, edge infrastructure, and good server placement become important.
But that doesn't automatically mean you need servers everywhere.
Sometimes fixing unnecessary requests gives you a bigger improvement than adding infrastructure.
Be careful with premature infrastructure
When developers discover latency, it's easy to jump immediately to:
“We need multi-region infrastructure.”
Maybe.
But first ask why the application is making those requests.
If one interaction triggers eight sequential API calls, deploying the same inefficient architecture to five regions doesn't solve the underlying problem.
Measure first.
Optimize second.
Scale infrastructure when the measurements justify it.
Measure what users actually do
Instead of only testing the homepage, test workflows.
For example:
Login → Dashboard → Open item → Edit → Save
Measure how long each step takes.
You may discover something interesting.
Perhaps the initial page load is excellent, but saving an item takes two seconds.
That's probably where optimization will have the greatest impact.
The Next.js documentation is a good starting point for understanding the framework's caching, rendering, and optimization options, but architecture still depends heavily on your application's actual behavior.
Performance is a system problem
Modern web performance isn't just:
“How quickly does my HTML load?”
It's the combined result of:
Frontend + API + Database + Network + Infrastructure + UX
That's why chasing a perfect Lighthouse score can sometimes send developers in the wrong direction.
A 100/100 score is nice.
But I'd rather have an application scoring 90 that feels instantaneous during real workflows than one scoring 100 whose users stare at frozen buttons after every click.
Measure the experience, not just the score.
Top comments (0)