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

แชร์
ฝัง
  • เผยแพร่เมื่อ 27 ธ.ค. 2024

ความคิดเห็น • 73

  • @mariusespejo
    @mariusespejo  ปีที่แล้ว +13

    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 11 หลายเดือนก่อน +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 ปีที่แล้ว +20

    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 8 หลายเดือนก่อน +1

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

  • @divinelogik
    @divinelogik 10 หลายเดือนก่อน +3

    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.

  • @noeldolan518
    @noeldolan518 ปีที่แล้ว +1

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

    • @mariusespejo
      @mariusespejo  ปีที่แล้ว +2

      Thank you! Using excalidraw there

  • @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.

  • @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

  • @_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

  • @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

  • @Psych134
    @Psych134 11 หลายเดือนก่อน

    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  11 หลายเดือนก่อน

      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 11 หลายเดือนก่อน

      @@mariusespejo thank you

  • @BimaAulia-fz1yt
    @BimaAulia-fz1yt 9 หลายเดือนก่อน

    Which next js version are you using?

    • @mariusespejo
      @mariusespejo  9 หลายเดือนก่อน

      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

  • @ayushjain7023
    @ayushjain7023 ปีที่แล้ว +5

    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

  • @MMEDHAT1910
    @MMEDHAT1910 ปีที่แล้ว

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

  • @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

  • @tifactlong7431
    @tifactlong7431 9 หลายเดือนก่อน

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

    • @mariusespejo
      @mariusespejo  9 หลายเดือนก่อน +1

      This caching behavior is for app router only

  • @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

  • @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

    • @PeterSiepen27
      @PeterSiepen27 ปีที่แล้ว

      @@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

  • @SamTipton
    @SamTipton ปีที่แล้ว

    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.

  • @oscarresonable2008
    @oscarresonable2008 ปีที่แล้ว

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

  • @rohitsaklanimca4thsem571
    @rohitsaklanimca4thsem571 5 หลายเดือนก่อน

    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 ☺

  • @dawid_dahl
    @dawid_dahl ปีที่แล้ว

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

  • @iPankBMW
    @iPankBMW ปีที่แล้ว

    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…

  • @aymenbachiri-yh2hd
    @aymenbachiri-yh2hd 2 หลายเดือนก่อน

    thank you for this video

  • @yavuzselimdogan9852
    @yavuzselimdogan9852 วันที่ผ่านมา

    There is also another problem: caching behaves different on localhost dev environment and production. If you solve the problem locally, still you can see cache related bugs on your prod environment.

  • @berlatoy
    @berlatoy ปีที่แล้ว

    Thank you so much for this explanation bro

  • @ausername4meplease
    @ausername4meplease 10 หลายเดือนก่อน +1

    Thank you for the explaination but, no solution :(

  • @nikako1889
    @nikako1889 ปีที่แล้ว

    is it fixed on nextjs 14?

    • @mariusespejo
      @mariusespejo  ปีที่แล้ว

      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 ปีที่แล้ว

      @@mariusespejo thanks for answer.

  • @AlfonsusAC
    @AlfonsusAC ปีที่แล้ว +6

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

  • @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!

  • @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"

  • @ibrahimo0682
    @ibrahimo0682 11 หลายเดือนก่อน

    just use

    • @mariusespejo
      @mariusespejo  11 หลายเดือนก่อน

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

  • @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 9 หลายเดือนก่อน

    😢😢 is the only option i guess

  • @shabadouwilou
    @shabadouwilou ปีที่แล้ว

    why hit refresh lol

    • @mariusespejo
      @mariusespejo  ปีที่แล้ว

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

  • @kumarvishalben
    @kumarvishalben ปีที่แล้ว +1

    super confusing

  • @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