Partial Prerender - The Next.js Feature I've Wanted For Years
Вставка
- Опубліковано 26 сер 2024
- I've wanted PPR for so long and I'm so hyped Next.js has added it. Cold starts are a thing of the past. I barely need edge anymore. Lambda users rejoice!
Blog post: vercel.com/blo...
Lee vid: • Partial Prerendering i...
Check out my Twitch, Twitter, Discord more at t3.gg
S/O Ph4se0n3 for the awesome edit 🙏
I laughed out loud when you say "that's my job" for reading the blog post. I was totally stealing your move 😂
This feels to me more of a Vercel feature than a Next.js one. You can't easily configure existing edge CDNs to serve static and dynamic content from a single request
Vercel is turning more and more of the 'improvements' to Next.js to Vercel native features and it's sickening
Isn't this the case for most of the Nextjs features like image optimisation and other things?
@@codedusting you referring to image optimisation plus CDN in particular or? As far as I know, if you deploy Nextjs on a barebones VM or in a Docker container and run it using next start or using standalone build, all those features should still work because Nextjs server is being used to start and operate the app. I've never had issues with deploying like that and all Nextjs features worked, although I mostly work on private apps so there is no ridiculous amount of traffic and CDN and these other things Vercel talks about aren't really needed.
When you get into these more complicated setups with edge, CDN etc is where things might get a little trickier. One project I know that handles bunch of this for you is called SST and it deploys to AWS with bunch of this stuff set up automatically for you.
@@rand0mtv660 I see. I am stuck with GCP App Engine because of client requirements. And there is no way of knowing when the next image optimisation stops.
@@codedusting try to find some information in their docs about supported features of nextjs if there are docs about that. I don't know anything about GCP App Engine, but if it wraps your app inside a container and just runs nextjs server, you are most likely using all nextjs features.
Vercel: Not yet recommeded for production use.
Theo: Let's use it in prod! :)
We need standard web caching using headers and not nextjs’s proprietary file based solution. That’s why I love remix, we can do the same thing there but using standard caching mechanism of cdn and not only vercel
Nothing stops you from use state-while-revalidate and other caching mechanisms in Next.js, but that's not the only thing that's going on here. You _may_ get similar behaviour through defer, but I haven't tested that yet and what the differences are.
@@dealloc my main point is that we need some open standards and not the way of switching off fetch based caching or implementing our own caching later. We need a solution that works everywhere from start and not only on vercel and then to refactor everything to make it work on other hostings
The funny thing is that vercel will benefit from this too, but they don’t understand this
Its cool to see how far Next.js can take React, but in the end Vercel is a private company so you always have to be cautiously optimistic.
Would've been even worse if it were a public company
@@orere1635 Yup, both are true.
i don't want to watch you watch someone explain it... just explain it...
I agree. This is just turning into Theo Reacts
Does this only work if you host on Vercel? Seems like it’s relying on their edge network, how would this work on self hosted next.js for example?
For the more Junior devs (like me), the "next-learn/dashboard" project tutorial they have is a great step into Next.js 14 to get a feel for it. The partial pre-rendering is siiiick.
I'm coming into Next.js at exactly the right time, I think. This and their router system are exactly what I felt was missing when I learned CRA, haha.
Here to also endorse the new next tutorial for being a great introduction and a great way to learn by doing with Next, doesn't feel like there's enough of that online
This is awesome to hear. I’m planning on jumping into next 14 and I was really intrigued by their tutorial. Now I’m definitely going to (as another junior dev)
Just finished it today, pretty good for someone who hasn't worked with next before. But Some sections could still be improved.
That being said I look forward to make projects now to truly understand how next works
@@__-yz1ob definitely some improvement to be made. I've already submitted some issues to GitHub for them, and they seem to be getting to the issues every few days or so.
Will this also work properly outside of Vercel? Does Vercel handle the CDN part automatically? So this would mean I need to setup my own CDN when deploying Next myself?
I feel like we're coming back around to the behaviors we tried to leave behind with a classic SPA.
Theo always mentions how bad SPAs are, and gives twitter(X) as an example: "you go into the page, see some data first and then you have all this loading spinners until all your data fetches".
now with partial pre rendering we'll have the same behavior (just a bit faster), same as the previous example just instead of "fetches" we'll say "streamed in".
and you'll get a ""you go into the page, see some data first(faster cuz you don't download the whole js bundle) and then you have skeletons(the cool loading spinners) until all your data is streamed in".
All this guy does is bandwagon don’t take him seriously
Your comparison is wrong, on an SPA, the client first gets a js bundle, then executes that JS to fetch the rest of the page which means the sever doesn't start processing dynamic content until then, whereas here, the rest of the page starts getting generated as soon as the first request hits. It's a difference that could easily be 400ms.
There's no way around loading fallbacks in complex UIs. Twitter sucks because there's so much layout shift, not because it behaves like a SPA. Imagine if Twitter suspended showing any content until all the requests resolved, that would certainly be worse! SPAs are not bad because they have loading feedback in them -- they're "bad" because of the time it takes to see content. I understand that the differences can feel negligible sometimes though
To be able to render your static content, loading UI for your dynamic content while it streams in, and do it all in a single round-trip is pretty freaking cool though
@@EAlexHaywood The worse thing about SPAs is actually not the time it takes to see content but the time it takes to actually use content you see.
Eliminating any extra round-trips feels like progress. But more than that, because Next aggressively pushes static rendering, you will typically find that if a page has rendered previously on the server (SSR), it will get returned instantly without having to run any React at all, for the next user (ISR).
Now with PPR, your pages dynamically become "static" even if they have some dynamic components in them (the whole page still renders, but the static parts of the previous render get served before that). So your server is reusing rendering work in the most efficient way possible, which means a significantly faster UX.
My question here is do we still consider this SSR? in terms of first loading and streaming data later what does a crawler see? I remember that we kind of moved away from plain lib/frameworks like React etc specifically for SEO related problems. Although this seems very cool I wonder, are we going back to the first paradigm?
1. Yes, all the content is still rendered on the server, so this is still SSR
2. Crawler will see the initial state by default. Smarter crawlers by co's like Google will be able to parse full response, but will (likely) expect enough metadata in initial response to operate
Next.js solved the SEO problem 7+ years ago. The problem was that it rendered EVERYTHING. It can now render just the essentials in a static shell that is cache'd, and that shell will almost certainly include all the metadata needed for SEO
@@t3dotgg Nonetheless I am perplexed. Sure, let's assume that the relevant metadata will be there for the crawler to see, but what about the rest of the content? So many developers are pushing for semantic HTML, what about indexing content on the page? I defo need to try this one before giving any comment but as far as I see it now it seems to be something more for score than actual performance. Your Lighthouse scores are always gonna be green I mean time-to-first-byte super quick and the page is immediately interactive but it's an empty shell. I really liked the quote Rich harris once said, which he was quoting from Goodhart's law "When a measure becomes a target, it ceases to be a good measure". I might be wrong of course
Thanks for explanation the diff between PPR, SSR and ISR by showing the real requests in the network tab! With dev tools it is so much easier to understand what is it you are talking about :)
Ahh... Definitely. I've wanted this feature for a long time.
This is pretty cool, but having to make sure stuff loads in the right order and avoiding layout shift scares me. For something like a view counter this sounds amazing, but if I had a page where all the user cares about is dynamic content I might still be inclined to use a global loading spinner and instead focus on making my backend as fast as possible.
This sounds like the standard “render as you fetch” technique that Facebook has been using for years with relay and graphql. Relay is more difficult to learn. But, is a very elegant solution, once you get the hang of it.
PPR looks great! This is pretty much what I want from nextjs. Will it only work on vercel? Or will it work with open next/amplify?
Our backend will be hosted in aws. So we'll ideally want our next server to be close to that (in the same vpc if possible).
Had no clue that it was not working on Vercel 😂Good thing they fixed it quickly!
It is something we have been applied to SPA for years for a more performant manner,,,, for each entry of a page, instead of using a blank index.html, we give it a bit of a flavor by adding a loading skeleton. Good to see that next.js finally catching up, but not quite, SSG makes more sense in this case.
I want PPR on Astro soon!
For people saying this is a Vercel feature hack, I don't use Vercel, and I don't even use the integrated NextJS server with middleware, I use a custom server, which is only documented for the Pages router. However almost all the features of the NextJS 14 app router including PPR work.
I'm not getting it. Is it not the same thing that was shown with the use of suspense when next 13 came out? I remember examples of the same thing already there.
Previously, the Next.js server had to send the first response, so you had to wait until that server spun up, processed the request, and generated a response. Suspense allowed for additional data to come down.
Now, the first response can come from a CDN. The Next.js server does not need to spin up before the user can get a response back.
When you deploy your entire app as pre-compiled WASM, you can serve the entire app from a CDN.
theo finally fixed his video
The biggest downside i faced with this model was the soft 404 issues as the page actually can't decide to respond with 404 until the dynamic parts are fetched
but with this model you will always get 200 response as static parts always came at first with 200 response then came the rest of the page with 404 but it's too late
this happens alot at ecommerce and marketplaces websites
So basically we are back to SPAs. The only reason why someone would even consider using a meta framework is due to SEO benefits we get. If I am not gonna get the initial HTML, I'd prefer using plain React with Vite because it's faster and yeah metadata isn't the only thing we need for SEO. I need fully rendered HTML.
Isn't this another form of hydration? Or suspense? Some kind of mixture.
does it run longer than 10 sec, Vercel limit on a function in hobby plan?
finally a good content about this 😊
What is the difference between streaming using suspense vs partial pre rendering? I was going through the next 14 tutorial on their website and this thing confused me
That when you’re partially pre rendering you store the static html on a cdn, which results in a faster response time on initial loading
With streaming, you can load in individual parts as they render.
With PPR, you can render parts of it ahead of time, send those parts instantly, then stream the rest of the page in instead of streaming 100% of the page.
@@connorskudlarek8598 Sry, I am still confused. Your definition of PPR is what I thought streaming did. Isnt streaming loading the static content of the page right away and then "streaming" the slow, dynamic data as it loads?
That fucntion call noStore() what does it do under the hood? What APIs does it encapsulate in rider to make that single component dynamic?
@Theo But when opening partialprerender website's source, you can still see recommendations prerendered with comments and everything in initial document, so is it just SSR? Why was there a loader placeholder on the FE then?
I understand how PPR works now, but how is this different from the existing loading.tsx suspense convention where data is streamed in?
I'm curious how it works with loading.tsx; Is this still necessary for partial prerendering?
The layout.tsx file is mainly for showing common elements among many pages. Headers, sidebars, footers, and some other UI are shared elements that stick around.
It isn't "necessary" to have one in the first place, but PPR doesn't replace it, no. You might even want to include some partial pre-rendering for it, such as a user name or profile picture that will be shared throughout the application pages.
Since the layout.tsx file only renders once and maintains state, that would stop you from needing to render the username and profile image for every page.
@@connorskudlarek8598 You def need to re-read that comment
No. I don't think I do?
The layout.tsx doesn't partially render the page. It fully renders the UI for MANY pages.
If your layout.tsx file only is used on a single page, then MAYBE you don't need it? But if you're using it for many pages, then you don't need to re-render the UI for EVERY page.tsx with partial prerendering. It would just be wrapped in your layout.
Why would you waste compute time re-rendering the same UI for potentially hundreds or thousands of pages when you could render it once and share it with every other page? That's very not DRY of you. :P
Not to mention, again, layout.tsx maintains state between pages. PPR doesn't necessarily do that.
@@mr.komp1004 can you clarify what you think I misunderstood?
From what I can tell, they're asking if there is any benefit to having a layout.tsx file now. Which the answer is yes.
In UA-cam for instance. The navigation bar at the top is the same on every UA-cam video. The only thing different is the profile photo.
Using a layout.tsx at the root for this makes sense. Partial prerendering of the layout.tsx file with a suspense component fetching my profile photo also makes sense. In this way, my profile photo is only fetched for the layout file and everything about my profile state can be stored in the layout.tsx (maintaining state about the user between page renders).
Anytime someone goes to a new video (page.tsx) the navigation bar at the top won't re-render a new one and it doesn't need to get the pre-rendered one from the server before you can interact with it.
You could go to a dead route and your layout will remain and it will remain interactive with state saved. That won't be the case for your error.tsx without a layout.tsx wrapping it (I am pretty sure).
Guy specifically asked about loading.jsx file, you are talking about layout, that part of NextJS 13 update, but doesn't correlate with the question at all@@connorskudlarek8598
I couldn't figure out how to use the tag system with (direct calls to db or server actions).
Lets imagine I have customers table that can be cached and left static.( since barely users are changing it).
In my component I would have
await getCustomers(); //direct db call;
I want to be able to re-validate this by tag rather than path.
it would be awesome if they had similar function to noStore(), tag('customers');
So that when you go and update a customer or add a customer you can say revalidateTag('customers') that will then prompt this component to refresh the cache.
I am aware that currently you can do that only with API's and fetch.
If you don't want next to cache the component, call a function called `noStore()` that has a side-effect of disabling caching? That's such a weird API.
It doesn't seem all that weird.
"Don't bother to cache this, this component is dynamic, so always render it." = noStore()
@@connorskudlarek8598 what it does is not weird. It's essentially setting a render configuration flag, that's fine. How you configure it is weird though. It doesn't look like a configuration at all.
@@MachineYearning ah, I see. I couldn't figure out why what it does was weird. But how it does it couldn't certainly be weird. :P
This looks a lot like the hx-trigger=“load” lazy loading of htmx 😊
Maybe I’m misunderstanding isn’t that the same as “defer”we got in remix a year ago ? I think it’s great and I’m looking forward to use it but I’m curious
yep, next caught up w this, still like the remix way, is a better dx IMO
I need help , How to use Framer-Motion with Nexjs when changing the route
I'm having a hard time understanding that what's new here? Didn't we have loading.tsx which wraps the entire thing in a . Also we had before too. I know I'm missing something. Want to know what. Did PPR improve the existing work around for ?
This is i think from Astro from the very before
how many times will the react route get "fixed"
How does the server gives "something" to the client, and *then* fill out the rest? websockets/pubsub/etc? because traditionally, when the browser does a request it expects a response and then the comunication with the server is gone
after thinking about it I suppose that it reads the stream of the request until some marker is read that signifies the first load is done, and render that while still reading the rest of the response? but can a server start sending the response and add things to the stream? or again, is an open channel type of thing? I'm a little lost lol
That's basically what Drupal does with Dynamic Page since 2015, isn't it?
i'm guessing RSC comes as a defined boundary in which those dynamic parts runs on(server/client) right?
What VSCode theme is he using in the presentation?
Fast edge delivery means from a CDN not edge render yea?
What makes this framework more desirable than svelte?
started feeling that these influencers are surely imposing on SSR, partial rendering etc when most of apps doesn’t need same.
Sir, this is a Remix
how about seo?
How does this affect SEO?
All I wanna know is where I start with node/next/react. I get a long way with the trinity and an amplify app.
Next-learn has a good explanation of going from JavaScript to React and React to Next.
In the meantime while watching the video, i see the number of likes here on youtube refresh (spin) automatically. Does this means that Angular (I believe UA-cam is build mainly in Angular) is having this feature long ago?
youtube uses polymer, not angular
Most likely the updated number of likes is fetched periodically and then just updated on the UI dynamically with animations. All this by JavaScript loaded on the page after initial HTML page response. Later updates to page content likely not part of initial streamed HTML page response, but by resources like JavaScript loaded based on that response
So we have CSR, SSR, ISR and now PPR lol
Been writing Next apps for 6 years and never used Suspense outside sandboxes and lols. Kinda dislike the pattern. No transition control without silly hacks. Nobody I’ve worked with ever wanted to use it, so we never did. I wonder if it’s even possible to apply Partial Prerendering on a self-hosted serverless setup, or if we’re stuck with running a next.js server in a VM to utilize this.
Don't they explicitly tell you in their docs how to self-host the entire app and any additional custom configuration you might want?
@@connorskudlarek8598They specifically don't tell you advanced self-hosting methods, just the "run the nodejs server in a VM" method. Many attempts have been made to get an open source distributed infrastructure going, but the road there is difficult and involves a crap ton of trial and error. OpenNext and SST gets most of the way there now with Next 13, but with each new version there are always new undocumented things to solve.
more
pushing/hyping a feature that 99% of projects do not need, but casually aligns with Vercel products. UX is already good if you CDN cache the whole frontend part, but sure let's keep changing the whole foundation of web development just to improve a marginal 0.1% performance (and make more moneyzzz)
Seems like overkill.. most bloated WP /shopify sites run just as fast lol
I FKN HATE REACT NOW!!
Honestly, I find almost no reason to use Next nowadays. Having Astro around makes it so that's it has so be something really specific to justify Next and all the shenanigans it comes with