What Next.js doesn't tell you about caching...

Поделиться
HTML-код
  • Опубликовано: 13 сен 2024
  • In this video we discuss some issues and confusion around how page and data caching works for NextJS, and we talk about the distinction between server and client caching and the settings which affect both. We also discuss the behavior of the next js Link component, how prefetch affects caching behaviors, and finally the distinction between soft vs hard navigation.
    Github Issue about stale pages: github.com/ver...
    Client cache semantics relating to prefetch: github.com/ver...

Комментарии • 71

  • @mariusespejo
    @mariusespejo  Год назад +11

    Just wanted to clarify: when I was trying to demo the 30s ttl, I should not have hit refresh just before (which might’ve already cleared the cache). I meant to show that clicking quickly shows cached data, but after 30 seconds it gets you a new one. Sorry I totally messed up 😂 but I hope it makes sense!

    • @AldisSv
      @AldisSv 8 месяцев назад +1

      Thanks Marius for clearing this up. Btw, I learn't these 30 seconds the hard way, just clicking back and forth with tag, and seeing that suddenly it starts behaving dynamically after some time. It started to fetch data on server side on each navigation. I just dont understand why it's not working like that right from the beginning, why exactly we need to wait those 30 seconds...

  • @WebDevCody
    @WebDevCody Год назад +18

    yup, I ran into this a while back and it's very annoying. The only fix I found it to add a client component on the page you know should be fresh data each time, and put a router.refresh() inside a useEffect on mount.

    • @EnesKab
      @EnesKab 5 месяцев назад +1

      Dude ! I am pulling my hair for the last 5 hours and your comment did the trick finally ! Thank you !

  • @divinelogik
    @divinelogik 7 месяцев назад +2

    Jesus dude. This is exactly what I was looking for. I legit tried all 5 strategies for blowing away the cache (no-store, force-dynamic, force-no-store, revalidate=0, React unstable cache), and to find that I was affecting only the server-side cache was mind-boggling. But this makes total sense. Short story: use to kill it entirely.

  • @ayushjain7023
    @ayushjain7023 Год назад +4

    To fix it just create a client component returning null, with router.refresh() inside a useeffect with empty dependency array, and add it in a server component, boom 💥 it will work

    • @mariusespejo
      @mariusespejo  Год назад +6

      Right, however It’s more of a hack than a fix. Nextjs needs to create a way to opt-out

  • @rohitsaklanimca4thsem571
    @rohitsaklanimca4thsem571 2 месяца назад

    There is still no solution about this in docs or videos . thanks to this video now I know It is not possible to invalidate the client side router cache ☺

  • @MMEDHAT1910
    @MMEDHAT1910 Год назад

    Hello Marius, your videos are great and of huge benefit. I started learning nest js by watching your videos. Keep going ❤️❤️

  • @dawid_dahl
    @dawid_dahl Год назад

    Thanks so much for making a video trying to clarify this. Very important stuff. 🙏🏻

  • @oscarresonable2008
    @oscarresonable2008 Год назад

    Very insightful. I'm actually scratching my head all day long wth is going on 😂😂. As always, Thanks Marius. Keep going brother.

  • @liu-river
    @liu-river Год назад +4

    Appreciate the explanation. Any chance you could do a video on deep dive on Next js caching and revalidation including, data cache, route cache, etc?

    • @mariusespejo
      @mariusespejo  Год назад +2

      Yeah I’ve actually been learning a lot about it in my own projects, I can definitely cover that in more detail. Have you seen the new docs for it? It didn’t exist at the time of this video

    • @liu-river
      @liu-river Год назад

      @@mariusespejo I have, it's not very beginner friendly. I kinda understand it but it gets quite complicated. Maybe it's one of those things that you will have to play with a lot and try out all different scenarios to fully grasp.

    • @mariusespejo
      @mariusespejo  Год назад

      Yeah I agree, I’ve had to read it multiple times to be honest and parts of it is still confusing haha

    • @liu-river
      @liu-river Год назад

      @@mariusespejo yeah, quick question though do you know if server cache actually works in dev mode, or is it production only?

    • @mariusespejo
      @mariusespejo  Год назад

      “Data cache” (server) I’m pretty does work in development because when I call fetch server-side the terminal logs tell me if they are cache HIT or MISS. If you look in the .next folder you also will see cached data in there. Although I have seen people saying cache doesn’t work in dev mode and what’s tricky is there are multiple caches right, and idk what people are talking about exactly. The docs does say however that link prefetching only works in production, and prefetching affects the “Route Cache” (client) behavior.

  • @_bouwer
    @_bouwer Год назад

    Oh my gosh, thanks for this. Hopefully the docs get updated soon.

    • @mariusespejo
      @mariusespejo  Год назад +1

      just an hour ago actually they posted a response/discussion on the github issue, where they fully explain why this 30s thing exists. It’s probably the best explanation we’ll get. I might cover it in a follow up video if I get some time

  • @noeldolan518
    @noeldolan518 8 месяцев назад +1

    Great video! :). BTW what is the flow diagram UI tools you're using @ 4:00?

    • @mariusespejo
      @mariusespejo  8 месяцев назад +2

      Thank you! Using excalidraw there

  • @AlfonsusAC
    @AlfonsusAC Год назад +6

    So im not the only one that is having trouble understanding this

  • @iPankBMW
    @iPankBMW 9 месяцев назад

    Thank you for this video! I went immediately to Nextjs docs and red the latest instructions - now they are mentioning it. And they say there is no way to opt out of the default 30 seconds server component payload cache (cliend-side/router-cache). That terible. So there is no way we can use server components for data fetching if you always need latest data from backend… So useless.. Gues for latest data from backend we still need to stack to client side components…

  • @SamTipton
    @SamTipton 10 месяцев назад

    I've only been learning next for just a week now, but this caching behavior makes sense to me because were doing SSR by default. Would have been interesting to see what would happen if you made it a client component.

  • @berlatoy
    @berlatoy 9 месяцев назад

    Thank you so much for this explanation bro

  • @j_pestana
    @j_pestana Год назад +1

    I knew about the issue, but I haven't had any problematic situation because of it so far on the little projects I'm playing with.
    Thanks man for this huntdogs investigation work, and clarification. Great job on explaining. I really had no clue about that "Meta-caching" (Server & Client) that was going on under the hood.
    I don't see any easy fix to this though...😢
    Is there an alternative to the Link component that could help?

    • @mariusespejo
      @mariusespejo  Год назад +3

      So to be fair I think 30s is small enough that it probably isn’t that big of a problem for most use cases. I think you can also use the native anchor tag instead of Link which would always go back to the server. Also you could manually call router.refresh() on mount … but yeah all the options are a little hacky. If the 30s (or 5min on prefetch true) doesn’t affect you then I’d just leave it. The problem is mostly for cases where you absolutely cannot get away with showing stale data

  • @ilijanl
    @ilijanl Год назад +2

    Great video and great explanation. I guess they do aggressive caching because of the lamda's cold starts/slow execution which makes the app slow otherwise. In my opinion caching (on every level) should always be opt-in. Something with "pre-optimisation is root of all evil"

  • @sr-juhahn
    @sr-juhahn Год назад +1

    I feel like exactly this problem is currently ruining my mental model of authentication with nextjs. I integrated supabase, into my nextjs middleware to check if the user has a valid session before routing to protected sites and sending the user to login if not. This works great, until the user clicks 'logout' on a protected page - at which point the protected page was loaded into the client cache and after that the user is still able to access the protected page, because the nextjs link and rounter will do a soft routing and my server middleware never get's another call if the user is allowed to go to the protected page and cannot redirect.
    Tried 'force-dynamic' on the server and also tried to manually set the header 'Cache-Control: no-store' to try to convince the browser to send another request to my middleware. Any suggestions for this kind of problem?

    • @mariusespejo
      @mariusespejo  Год назад

      They actually released new docs about the caching shortly after this video. The client-side cache that I talk about in the video is officially called “Router Cache”
      You can’t opt out of it unfortunately but they do give some options to invalidate. In your case you either need to router.refresh() on sign-out or you can use a server action to either use revalidateTag/revalidatePath (e.g. if you tagged your protected fetch calls), Or if you use cookies for auth, run cookies.delete() in a server action
      Either of those should do the trick but you’ll have to test out which one works best. If you’re trying to invalidate the server-side Data Cache in addition to the client Router Cache I think you have to use the revalidateTag/Path. Hope that helps
      nextjs.org/docs/app/building-your-application/caching#invalidation-1

  • @ibrahimo0682
    @ibrahimo0682 7 месяцев назад

    just use

    • @mariusespejo
      @mariusespejo  7 месяцев назад

      You can but you also lose the optimizations that the Link component provides

  • @tifactlong7431
    @tifactlong7431 5 месяцев назад

    How about in page router? All I see is app router revalidating route but I need also it in page router

    • @mariusespejo
      @mariusespejo  5 месяцев назад +1

      This caching behavior is for app router only

  • @Psych134
    @Psych134 8 месяцев назад

    Hey buddy, as of today is there any fix from nextjs team on this issue or do we still have to use work arounds?
    Anyway, great video!

    • @mariusespejo
      @mariusespejo  8 месяцев назад

      Not really (last I checked), there is a massive open discussion about this if you want to know where’s it at: github.com/vercel/next.js/discussions/54075
      But it really is a massive thread, but basically you still can’t configure this or opt out

    • @Psych134
      @Psych134 8 месяцев назад

      @@mariusespejo thank you

  • @ausername4meplease
    @ausername4meplease 6 месяцев назад +1

    Thank you for the explaination but, no solution :(

  • @BimaAulia-fz1yt
    @BimaAulia-fz1yt 5 месяцев назад

    Which next js version are you using?

    • @mariusespejo
      @mariusespejo  5 месяцев назад

      Not sure what I was using here, but the github ticket for this is still open so it’s still relevant in the most recent version today

  • @kaisian4940
    @kaisian4940 Год назад

    10:37, by right you hit refresh should get the new random value already no need wait 30s

    • @shabadouwilou
      @shabadouwilou Год назад

      thats what i was tinking but maybe i miss something

    • @mariusespejo
      @mariusespejo  Год назад

      Yeah I now realized I made that demo more confusing lol. The point was to show that prior to waiting you see cached, after 30 seconds the number is updated. I shouldn’t have refresh, good catch!

  • @kishansripada3392
    @kishansripada3392 Год назад

    experienced this issue myself. this clarifies so much! what's the best way right now to work around it? right before navigating to another page using router.push(), i added a router.refresh() but this doesn't seem to work.

    • @mariusespejo
      @mariusespejo  Год назад

      You can use router.refresh() on mount of the page you’re navigating to, like in a useEffect for example. Or you can use old school html tags to force it to go back to the server
      Basically all of the solutions are hacky, hopefully they’ll provide a way to opt out. Currently the newest docs literally say you can’t opt out and people are mad haha

    • @jaeken
      @jaeken Год назад

      @@mariusespejo cant do router.refresh() in a server compontent tho right?

    • @mariusespejo
      @mariusespejo  Год назад +2

      Right, it’s for client, which is where the router client cache is that we’re trying to invalidate. Btw next team did make a proposal for a fix that will let you configure the staletime but it might take them a while to implement

  • @bricelechatellier
    @bricelechatellier Год назад

    Thanks for covering this in details, does this happen to layouts as well? I have a layout handling user authentication with cookies and redirecting if the user is signed in but I get into a redirect loop after signing out as it's cached on the client. Any ideas how to fix the problem?

    • @mariusespejo
      @mariusespejo  Год назад

      Layouts do not re-render on navigation, that’s by design and is documented. You might need to force a router.refresh() in that case

    • @bricelechatellier
      @bricelechatellier Год назад

      @@mariusespejo Thanks, makes sense, I can do a router refresh on sign out but if my session expires I’m stuck with a stale state. Looks like I’m mis-using layout and need to wrap logic in pages, correct?

    • @mariusespejo
      @mariusespejo  Год назад

      Well in my mind you have to go to the server in some way, e.g. via a request to see if the session is still valid, and the request(s) should probably respond with maybe status 401/403. The client should then be setup to react to any request failing with that status and perhaps route to login screen and refresh

  • @LuisJimenez-uh1zx
    @LuisJimenez-uh1zx Год назад

    Hello, I have a simple application in nextjs and mongoDB, when I'm in development it does the crud fine, but when I deploy in vercel, it's like the front doesn't refresh the data, but it does manipulate the data, I don't understand why this behavior , even so, reloading the page does not work, it is as if at the time of doing the build it saved the data from this moment and only displayed that.

    • @mariusespejo
      @mariusespejo  Год назад

      The caching behavior for server-side only happens in prod I think, not in local. Depending on your use case you might need to set revalidate to how often you want it to, or use force-dynamic

    • @LuisJimenez-uh1zx
      @LuisJimenez-uh1zx Год назад

      @@mariusespejo thanks

  • @izumiosana
    @izumiosana Год назад

    honestly cache revalidation is one of the hardest thing in computer science.

    • @mariusespejo
      @mariusespejo  Год назад

      Yup but it’s even worst when you can’t opt out of it, or even control when it revalidates

  • @AshishKumar-ft6wv
    @AshishKumar-ft6wv 6 месяцев назад

    😢😢 is the only option i guess

  • @nikako1889
    @nikako1889 9 месяцев назад

    is it fixed on nextjs 14?

    • @mariusespejo
      @mariusespejo  9 месяцев назад

      Nope. You still can’t opt-out as of today. But there is an open ticket for it with a proposal from the team

    • @nikako1889
      @nikako1889 9 месяцев назад

      @@mariusespejo thanks for answer.

  • @kumarvishalben
    @kumarvishalben Год назад +1

    super confusing

  • @shabadouwilou
    @shabadouwilou Год назад

    why hit refresh lol

    • @mariusespejo
      @mariusespejo  Год назад

      I just realized what you meant 😂 yeah I totally messed that up haha

  • @oopss794
    @oopss794 Год назад

    many bad decisions are done in next js 13 ,

    • @mariusespejo
      @mariusespejo  Год назад

      Give it time, community will iron it out

    • @oopss794
      @oopss794 Год назад

      it's almost a year now since the conference

  • @felipefreire5245
    @felipefreire5245 Год назад

    Tthis is the worst thing i have ever seen Vercel do

    • @mariusespejo
      @mariusespejo  Год назад +1

      They did just recently comment on the github issue that they are looking at all the feedback and will address it somehow. Hopefully a better resolution in the future

  • @iukeay
    @iukeay Год назад

    Thanks for your amazing videos!