Lee Robinson Profile picture
Jun 20 1 tweets 4 min read Read on X
Here's where we're headed with caching in Next.js.

Last month, we shipped a release candidate for v15, which starts to address some of the community feedback on caching. tl;dr many parts are no longer cached by default.

In Next.js 15, if I make a fetch to some API, or make a database query, the result is not cached. This is something dynamic. If you want to cache the data, you can opt-in to this behavior. You need to be explicit.

I've seen a few questions floating around that I'd like to clarify 😁

What is prerendering?

Prerendering is where we try to generate a static HTML page during `next build`. This is separate from caching data fetching or database queries.

Today, there's "all of nothing" prerendering. Either your entire page is static, or it's dynamic from using a function that reads the incoming request. Ideally, we could have both together: send the static parts of the page to all users, while streaming the dynamic parts that are unique to the user.

Why is local development different than production?

When you're running your local dev server, and you reload the page, your components fetch new data—the results are not cached. You expect to see fresh data. In production, you might want to prerender the entire page to HTML and serve the same rendered page to all users.

When you create a production build, Next.js tries to prerender the application routes (since Next.js 9). In the Pages Router, this happens automatically when you don't use `getServerSideProps`. You can do additional data fetching for a static route using `getStaticProps`. Using `getServerSideProps` will opt you into dynamically rendering the route.

In the App Router, and with Server Components, you can fetch data from components. But just because I'm fetching data, doesn't always mean I want that component to be dynamically rendered. Some of my Server Components should be able to be prerendered to static HTML.

This isn't as explicit as the Pages Router APIs. Your page only becomes dynamically rendered when you read something from the incoming request. For example, reading `searchParams`, `cookies`, or `headers`. Doing a `fetch` does not automatically make the page dynamic today, because you might want that component to be prerendered.

Why not prerender in local development?

We believe the local dev experience should be as "lazy" as possible. Pages should compile on demand; you wouldn't want to wait for every single route to compile before you can get started.

Prerendering every route on save would be slow, which goes against our ambition to keep improving Fast Refresh times. With Fast Refresh, you can make a change to your code, hit save, and see the application update near instantly without losing your current client state.

I understand the desire to know whether the page will be prerendered or not during local dev, though. We used to show an icon in the bottom right of the screen, if the page would get prerendered. We're bringing this back!

Where are we headed with Next.js?

With the v15 stable release, we'll be writing more in the blog about our plans for the future. Our goal is to make all async operations (like doing a `fetch`) opt into dynamic rendering, similar to how using `headers` opts into dynamic rendering.

We believe Partial Prerendering will become the default way of building Next.js applications. In this world, routes can be both static and dynamic.

Even if the majority of your application is dynamic, you can still have a "shell" of your application that gets sent to the browser immediately, and then have the rest of your page (the dynamic parts) stream in parallel. This shell could even only be the link preload headers, for example.

If you want more of the route to be included in the prerender, you can wrap the dynamic parts of your page in React Suspense to define a fallback state. Next.js can then prerender up to that Suspense boundary as part of the build process. When serving the page, the user is immediately shown the prerendered HTML while simultaneously streaming the dynamic parts of the route.

Partial Prerendering is fully supported with `next start` (the production Next.js server) and is experimental today.

When can I try this out?

Next.js v15 stable will be released soon, which includes the previously mentioned default caching changes. Either in v15.0.0 or in a minor version soon after, we'll allow you to try the vision above for where we're headed behind an opt-in flag.

We're taking time to validate these early features with our own applications, some early partner customers, and the community to ensure they're well tested in large Next.js applications.

We're also working on simplifying the existing caching APIs and building DevTools for Next.js, which we feel are important pieces for completing the vision. More on this soon!

In conclusion, with Next.js 15:

• `fetch` requests are no longer cached by default
• Route Handlers are no longer cached by default
• Client-side navigations will no longer keep a cached version of the last page for 30 seconds when using `` or `useRouter`

We'll also make it easy to keep the existing behavior, if you prefer, in the upgrade guide. Okay, that's all for now!

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Lee Robinson

Lee Robinson Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @leeerob

Aug 24
So, you want to load a cat photo (i.e. the majority of the web).

This image is a high quality .jpg — 3.9mb and 3024 × 4032.

Look, I love my cat (and she thinks she's a wizard), but this is too large.

Here's how Next.js can help. A photo of my siamese cat, Fiona, sitting on a broom.
Let's start by bringing in `next/image`.

It's a small abstraction over the `<img>` tag. It's going to help us handle making the page load fast and without visual jank.

<Image src="/cat.jpg" width={3024} height={4032} />

But hmm, this doesn't look right. The photo of my cat is taking up the entire browser height and width, but it's cut off at the bottom. The cat photo is too large.
I'm getting an error in my editor because I didn't add an `alt` tag.

The `<Image>` component tries to help make the web more accessible, so adding an alt tag is required.

While it's great the image loads without layout shift, the image is way too large. Let's fix that.
Read 18 tweets
Dec 18, 2023
You have a `Request` – how do you get the visitor geolocation?

Just wrote new docs for @nextjs and wanted to share some of the interesting bits ↓
The `headers()` function allows you to read from the incoming request. For example, here we're pulling `x-forwarded-for` (or `x-real-ip`) in a function. Example code snippet reading the headers function to get the x-forwarded-for value.
The `getIp` function can then be used in any Server Component. But we want the location, not the raw IP!

P.S. in the future with Partial Prerendering, you can use Suspense to wrap the dynamic component, allowing the rest of the page to still be prerendered. Code example of using a suspense boundary to wrap an IP component, which consumes the getIp() function to show the x-forwarded-for header.
Read 7 tweets
Feb 9, 2023
2023 State of Databases for Serverless & Edge

An overview of 30+ solutions and emerging trends ↓
I'll focus primarily on transactional workloads in this thread.

Tools that pair well with serverless and edge compute – and tools that are designed to integrate with JavaScript and TypeScript codebases.

Okay, let's begin!
A new programming model is emerging. Developers want to:

◆ Abstract manual connection management
◆ Learn once and write everywhere with Web APIs
◆ Use tools that enable type-safe access to data

Complexity is shifting to be managed by the database vendor.
Read 8 tweets
Jan 29, 2023
Next.js is a free open-source framework. The creators, Vercel, fund its development.

How is this possible? Why would they give it away for free? Let's talk about funding open-source software (OSS).
2023 will be the year of hyper rationalization for how OSS is funded.

More companies are going to need to sponsor maintainers, and engineers need to do better due diligence for how projects are maintained and funded.
Behind many successful OSS projects, there's a successful business or crowdsourced funding.

In the case of Next.js, Vercel is subsidizing R&D by building a platform for developers to iterate and deploy their Next.js site.

But why?
Read 10 tweets
Oct 26, 2022
⬇️ Everything we launched at Next.js Conf yesterday
1. Next.js 13 – with some of the top requests from the community.

Try out next/image & @​next/font in `pages/` today + incrementally adopt the new router in the `app/` directory as you're ready.

2. We're working on a *lot* of educational content about the new features, conventions, and patterns for building your applications.

Here's a nice thread from one of our community members.

Read 10 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us!

:(