Loading
Skip to content
RAWINRAWIN
HomeAboutProjectsBlogUsesResumeAnalyticsContact
Orbit
00%read
The Dev Log

What Actually Makes a Next.js App Feel Fast

Fast isn't just about load time. It's about how quickly an interface becomes useful, how little work the browser has to do, and how well the application responds after the first render.

Written by
Rushan Siddiqui
Published
September 23, 2026
Reading
5 min read
Filed
Next.js

Filed under

  • #Next.js
  • #Performance
  • #React
  • #Web Development
  • #Frontend
All entries

A website can have a fast server and still feel slow.

It can have a good Lighthouse score and still feel slow.

It can load quickly on your machine and feel sluggish on someone else's phone.

Performance is not just about how quickly a page finishes loading.

It is about how quickly the interface becomes useful.

That distinction changes how I think about performance in Next.js.

Start With What the User Actually Sees

A user doesn't experience your database query time directly.

They experience the screen.

If the important content appears quickly, the page can feel responsive even while secondary work continues in the background.

This is why the first question should not always be:

How do I make the server faster?

It should be:

What does the user need first?

Load the important content first.

Delay what can wait.

Avoid making the user wait for something they don't need yet.

Performance starts with prioritization.

What the report recordsrequestfirst paintcontentinteractiveHow the wait feelsfeels responsive
Diagram·Rendering timeline

Server Rendering Is a Tool, Not a Goal

Next.js gives you several ways to render content:

  • Server Components
  • Static rendering
  • Dynamic rendering
  • Client Components
  • Caching

The mistake is treating one of them as universally better.

A mostly static page does not need to become dynamic just because the application has a database.

Likewise, interactive UI does not need to move entirely to the client.

The useful question is:

Where should this work happen?

Keep data fetching close to the server when the browser doesn't need to own it.

Keep interaction on the client when the user needs immediate control.

The architecture should follow the behavior of the interface.

JavaScript Has a Cost

Every piece of client-side JavaScript has a price.

The browser has to download it.

Parse it.

Compile it.

Execute it.

And sometimes keep it running.

A component that only displays text doesn't necessarily need to become a Client Component.

A simple interaction doesn't always need a large library.

A visual effect doesn't always need JavaScript running continuously.

Less client-side work usually means less work for the browser.

That matters even more on mobile devices.

Images Can Quietly Become the Biggest Problem

A beautiful interface can still feel slow because of one oversized image.

Large assets affect loading time, bandwidth, memory usage, and rendering.

The solution isn't to avoid images.

It is to serve the right image at the right size.

Use appropriate formats.

Avoid loading images that are below the fold before they are needed.

Do not send a desktop-sized asset to a small mobile screen when a smaller version is enough.

Performance is often decided by the assets you don't notice.

Loading States Should Feel Intentional

A page doesn't need to display a spinner every time something takes a moment.

Sometimes a skeleton is useful.

Sometimes keeping existing content visible is better.

Sometimes an optimistic update makes the interaction feel immediate.

The important part is that the interface communicates what is happening.

A blank screen makes the application feel broken.

A deliberate loading state makes the same delay feel understandable.

Perceived performance is partly an interaction design problem.

Caching Changes Everything

If the same data is requested repeatedly, fetching it from the database every time is rarely necessary.

Caching can reduce repeated work and make responses much faster.

But caching also introduces another responsibility:

Knowing when the cached data is no longer valid.

A stale cache can be worse than no cache when users expect their changes to appear immediately.

Good caching is not simply:

text
Cache everything.

It is:

text
Cache what can be reused.
Invalidate what changed.
Keep the source of truth clear.

The best cache strategy depends on how often the underlying data changes.

Don't Optimize What You Haven't Measured

Performance work becomes much easier when you know where the time is actually going.

A slow page might be caused by:

  • Too much JavaScript
  • Large images
  • Slow database queries
  • Waterfall requests
  • Expensive client rendering
  • Third-party scripts
  • Poor caching
  • Layout shifts
  • Slow network conditions

Guessing usually leads to unnecessary work.

Measure first.

Then fix the largest bottleneck.

Then measure again.

Optimization should be a loop, not a feeling.

Fast Is Also About Stability

A page that appears quickly but constantly shifts around doesn't feel particularly fast.

Neither does an interface that responds immediately but freezes during interaction.

Performance includes stability.

Keep layouts predictable.

Reserve space for content that hasn't loaded yet.

Avoid unnecessary re-renders.

Don't block interaction with work that can happen later.

A stable interface feels faster because the user doesn't have to constantly adjust to it.

The Browser Shouldn't Have To Do Everything

One of the biggest performance improvements can come from simply moving unnecessary work away from the browser.

The server can fetch data.

The framework can render content.

The CDN can serve cached assets.

The browser can focus on what it is actually good at:

Displaying the interface and responding to the person using it.

This doesn't mean client-side code is bad.

It means client-side work should have a reason to exist.

The goal isn't zero JavaScript.

The goal is useful JavaScript.

Fast Enough Is a Product Decision

There is always another optimization.

Another dependency to remove.

Another request to cache.

Another component to rewrite.

At some point, optimization stops being useful and starts becoming engineering for its own sake.

The right target depends on the product.

A dashboard with live data has different performance requirements from a documentation site.

A portfolio has different constraints from an online store.

Performance budgets should reflect what the user actually needs.

The Real Goal

I don't think a fast Next.js application is one that simply scores well on a performance report.

It is one where the interface becomes useful quickly, stays responsive during interaction, avoids unnecessary work, and remains stable while everything else happens around it.

The framework gives you the tools.

Server rendering.

Caching.

Streaming.

Code splitting.

Image optimization.

The difficult part is deciding when to use them.

Good performance is rarely about one clever optimization.

It is usually the result of many small decisions that all reduce unnecessary work.

The best-performing interface is often the one that simply asks the browser to do less.

  • #Next.js
  • #Performance
  • #React
  • #Web Development
  • #Frontend

Written by Rushan Siddiqui

✦
Previous entryDesigning Interfaces That Don't Fight the User5 min readNext entryThe Hidden Cost of a “Fast” Website5 min read

Site footer

Contactrushansiddiqui5262@gmail.com
Elsewhere
Open to opportunities

© 2026 Rushan Siddiqui. Creation Defined.

Elsewhere

© 2026 Rushan Siddiqui. Creation Defined.

Made with logicShaped by curiosityBuilt with purposeMade with logicShaped by curiosityBuilt with purposeMade with logicShaped by curiosityBuilt with purposeMade with logicShaped by curiosityBuilt with purpose