Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory Leak on route navigation #15239

Open
warflash opened this issue Oct 22, 2022 · 15 comments
Open

Memory Leak on route navigation #15239

warflash opened this issue Oct 22, 2022 · 15 comments

Comments

@warflash
Copy link
Member

Environment


  • Operating System: Linux
  • Node Version: v16.14.2
  • Nuxt Version: 3.0.0-rc.12
  • Nitro Version: 0.6.0
  • Package Manager: npm@7.17.0
  • Builder: vite
  • User Config: -
  • Runtime Modules: -
  • Build Modules: -

Reproduction

https://v3.nuxtjs.org/getting-started/introduction

Describe the bug

repeatedly switch tabs from e.g. get started to guide and watch the memory increase.
Fresh load
image
After 30 swaps
image

Additional context

For bigger pages this results in 100s of leaked MBs within only a handful of route changes which in turn makes switching routes take seconds and is really bad user experience.

Logs

No response

@warflash
Copy link
Member Author

warflash commented Oct 22, 2022

@danielroe Just to make sure, this seem like its not limited to the docs (since you added the docs label) and common behaviour
After publishing our nux3 migrated site we've immedeatly seen reports of people experiencing 15+ second route changes after using the app for a while, accumulating >1gb of ram. Used the docs to validate that the memory leak was not an obvious one and our fault but rather seems a nuxt thing since the docs behave the exact same

@danielroe
Copy link
Member

@warflash Can you identify any commonalities between your site and the docs? (Are you using Nuxt content, for example?) Are you able to provide a minimal reproduction?

@warflash
Copy link
Member Author

warflash commented Oct 23, 2022

Hey @danielroe we are using content indeed, so I tried removing it and the issue persisted.
I do not have a minimal reproduction but the same behaviour can be see with nuxt movies which you guys recently released, which is somewhat minimal I guess? https://github.com/nuxt/movies
https://movies.nuxt.space/search
swapping back and fourth between any page takes up ram which even when force garbage collecting is not given back. It doesnt grow as quickly as in our app here, probably due to the app being simpler but the behaviour is the exact same.
Initial load:
image
20 swaps or so between /search and /tv, force gc'ed afterwards:
image
Seems to be even worse on firefox, gotten up to 60mb on movies with just a few navigations.

@warflash
Copy link
Member Author

Oh and same issue on nuxt hackernews, which again, not the most minimal but just goes to show it seems like a really common issue. Swap between https://hn.nuxt.space/news/1 and https://hn.nuxt.space/newest/1 and slowly see the memory rise and keep allocated after GC's. Also verified same nuxt HN behaviour on firefox

Copy link
Member

Would you try adding the following to your nuxt.config and letting me know the result?

export default defineNuxtConfig({
  app: {
    pageTransition: false,
    layoutTransition: false,
  },
})

@warflash
Copy link
Member Author

Unfortunately that doesnt seem to help, also tried with a local clone of nuxt movies and didn't reduce the issue there either

Copy link
Member

@warflash Are you sure? I've been trying with Nuxt Movies locally and it greatly reduces the issue. (Note that you'll almost certainly need to build + run it in production mode to confirm.)

@warflash
Copy link
Member Author

Oh ok, I just tested in dev mode as the behaviour there was the same as in prod. Will recheck with a built project

Copy link
Member

I often regret interim updates, but - 🤷 - my current hypothesis is that this is an issue with <Suspense> + <Transition> preserving the context in the pending branch, meaning every click handler (for example) preserves a reference to potentially thousands of removed DOM nodes.

Having entirely disabled <NuxtPage> and <NuxtLayout> in the Nuxt Movies project, I still get the behaviour with the following template. (If you want to replicate, you will also need to swap out the auto-imports of useRoute and useRouter to be from vue-router for as pure a Vue experience as possible).

<template>
  <div>
    <RouterView v-slot="{ Component }">
      <template v-if="Component">
        <Transition mode="out-in">
          <Suspense>
            <component :is="Component" />
          </Suspense>
        </Transition>
      </template>
    </RouterView>
  </div>
</template>

https://vuejs.org/guide/built-ins/suspense.html#combining-with-other-components

Removing <Transition>, either from the template above, or if using NuxtPage, via app.pageTransition and app.layoutTransition greatly reduces the issue in my testing (that is, in the Nuxt Movies repro, decreases leak from 1.7Mb per navigation to 70Kb). Nevertheless, there are still some preserved detached DOM nodes from the pending state of <Suspense> , which suggests that the real core issue here is coming from <Suspense>.

The next step is likely to attempt to reproduce using Vue without Nuxt to confirm my hypothesis.

Possible causes I've ruled out:

  • NuxtLink's intersection observer implementation
  • NuxtLayout
  • NuxtPage and page progress hooks
  • useHead

@danielroe danielroe self-assigned this Oct 23, 2022
@warflash
Copy link
Member Author

warflash commented Oct 23, 2022

Yep you were correct, that does fix the memory accumulation of repeated navigations indeed. There still seems to be a bit of weirdness left though. Visiting different routes (not the same ones over and over) does also make the memory go up and never deallocates.
image
Not sure if the cause for that is the same (as in: any navigation allocates memory that's never given back, setting page and layout transition to false prevents repeated allocations for the same route but on different routes you still end up with the same behaviour)


Right in time for your update, gotta read through that first 👀

@danielroe
Copy link
Member

Baby's up from his nap, so I'll have to come back to this later. If you get a chance, would you try to replicate with https://github.com/nuxt-contrib/vue3-ssr-starter? It'll be tricky as it's so much smaller a project, but 🤷‍♂️

@warflash
Copy link
Member Author

Gotcha, got a pretty tight schedule today unfortunately but should I get to it I'll post it here. Enjoy family time and the rest of your sunday!

@nWacky
Copy link

nWacky commented Oct 4, 2023

I believe I have a similar memory leak

I have created this reproduction with nuxt 3.7.4

  • Initially (on page /) the website takes up 2.4mb of ram.
  • After navigating to /page/first or /page/second the ram is 4.2mb.
  • After navigating back to / and forcing gc in chrome devtools, the ram is 4.3mb
Screenshot after navigating to/from page, after GC

Tested for production build in Chrome without vue devtools plugin

Memory inspector in Chrome points to context in t in entry.js:

function xu(e, t) {
  // context t is pointing around here
  const n = (r) => {
    if (!r._vts) r._vts = Date.now();
    else if (r._vts <= n.attached) return;
    Me(Pu(r, n.value), t, 5, [r]);
  };
  return (n.value = e), (n.attached = Tu()), n;
}

It seems to be retaining something in createInvoker()

The issue is probably somewhere in vue, and probably due to using @click. This vue only reproduction seems to have the same issue

Also, sometimes after leaving a tab a few minutes running, some of the ram allocated for
/page/first is cleared (not by gc).

@staaph
Copy link

staaph commented Feb 5, 2024

image

we are facing the same issue. Between routing the dom nodes & memory increase. A bunch of detached elements are still kept in memory.

Picture is from node inspector, while running a local build of our app.

@waldi
Copy link

waldi commented Feb 13, 2024

We are also struggling with terrible memory leaks.
image
At some point the service crashes and is being restarted.

image
image
image

Discord Thread:
https://discord.com/channels/473401852243869706/1204168609547427870

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

5 participants