vue-i18n icon indicating copy to clipboard operation
vue-i18n copied to clipboard

Memory Leak SSR

Open Pindar opened this issue 6 years ago • 15 comments
trafficstars

vue & vue-i18n version

vue-i18n v8.11.2

Reproduction Link

any SSR usage

Question

In line https://github.com/kazupon/vue-i18n/blob/master/src/mixin.js#L58 a new object is created server-side because we are in beforeCreate. This is necessary to get the languages rendered server-side as far as I can see but at the same time it generates a memory leak because the destructor is not called by SSR. Do you have any ideas how to overcome this issue?

Pindar avatar May 27 '19 15:05 Pindar

Is there an older version of vue-i18n without this memory leak? Or a temporary workaround?

mathieumagalhaes avatar Jun 03 '19 10:06 mathieumagalhaes

Dirty hotfix, but it works with Nuxt. Not making a PR because it should be written in a better way. Just made as a quick hotfix for myself in urgent situation. If anyone need urgent but dirty hotfix: https://github.com/Airnauts/vue-i18n/blob/hotfix/master_memory-leak/src/mixin.js

bpsushi avatar Aug 20 '19 10:08 bpsushi

I suppose we are talking about this instance?: https://github.com/kazupon/vue-i18n/blob/f42e81f65a88eeeccc311b970d2d4fd4181712ed/src/mixin.js#L64

This extra instance is only created when there is a i18n component option defined in the component.

So this probably doesn't affect that many people but still bad if really happens.

But I wonder why is beforeDestroy not called on SSR. Is it normal that it isn't or something else is preventing it from being destroyed? Anyone knows?

rchl avatar May 27 '20 20:05 rchl

I've just tested this on Nuxt and I can't reproduce the leak.

On the server-side, the VueI18n instance is created for each request and beforeDestroy is not called but I don't see any memory increase even after loading the page thousands of times.

Not that the current vue-i18n code doesn't even null-out the this._i18n property: https://github.com/kazupon/vue-i18n/blob/e41736b291652798cf786591addd26e944437bf1/src/mixin.js#L117-L138

rchl avatar May 27 '20 21:05 rchl

I'd love to see a repo that reproduces this issue, if you have any. The issue could actually be somewhere else in your code, for all I know.

rchl avatar May 27 '20 21:05 rchl

@rchl The beforeDestroy hook hammered our employers system. What I did to evaluate the performance is I called return in the beforeDestroy hook without doing any further steps from the function and actually can see the improvement.

So employer has an dashboard and they transition from one page to another page and at that time the i18N components gets destroyed. it takes 20s for transition from one page to another. after returning out from the function it takes ~4s to transition.

vishaldodiya avatar Jun 08 '20 20:06 vishaldodiya

@vishaldodiya this bug is about SSR and in SSR beforeDestroy hook is not even called. So not sure what you mean really.

If you mean on navigating on the client-side then it's some other issue.

rchl avatar Jun 08 '20 20:06 rchl

I think this might be the same issue at nuxt: https://github.com/nuxt-community/i18n-module/issues/1039

I just reproduced with the latest nuxt/i18n versions.

I created a reproduction repo with documentation how it is setup and how to reproduce it: https://github.com/leonardlin/nuxt-vue-i18n-memory

leonardlin avatar Oct 10 '21 14:10 leonardlin

still provided, that the nuxt-ssr-i18n is the same issue. Just looking at the code, @bpsushi hack looks correct.

In SSR situation beforeCreated is Server Side, but all the clean-up is client side.

Steps:

  • I forked this vue-i18n,
  • implemented @bpsushi fix
  • included my hacked vue-i18n library to the reproduction repo: https://github.com/leonardlin/nuxt-vue-i18n-memory
  • The problem is still reproduciable.

I went so far to remove all beforeCreate stuff and it still happened.

To me it seems that the watchers (that are cleaned up in beforeDestroyed) are not the only thing problematic. There might be something else going on.

weird.

leonardlin avatar Oct 10 '21 20:10 leonardlin

Update: It seems to happen in combination with vue-i18n in dev-mode. In prod-mode I can't reproduce it either. Still investigating, will report if I can reproduce again.

leonardlin avatar Oct 11 '21 21:10 leonardlin

@leonardlin Thanks a lot!

I'm doing OSS development while working at my day job. I will be working on this issue, although I may be a little slow to respond. 🙏

kazupon avatar Oct 12 '21 02:10 kazupon

Update: I couldn't really trace it down to the function that is causing it (profiler crashed the node instance). From the memory-dump it looks like the watchers grow a lot and the arrays grow a lot. It is not related to the mixins (I removed them all for a test).

My latest hypothesis is that it's related to the setup with each request (install/constructor) and watchers because in dev-mode there are all these hot-reload watchers that don't exist in prod.

I'm not sure how critical this bug is, since it's a dev-mode issue only.

leonardlin avatar Oct 12 '21 05:10 leonardlin

As mentioned in a couple first comments here, this issue seemed to be related to using the <i18n> element within a component. So this issue is quite specific and not necessarily what you are seeing with Nuxt. Also I'm not sure sure if this is even an issue anymore.

As for the Nuxt issue that you've linked (https://github.com/nuxt-community/i18n-module/issues/1039), as discussed in related PR (https://github.com/nuxt-community/i18n-module/pull/1040), that one is dev-specific issue due to how Nuxt works. See the PR for more info.

So I would not confuse those two.

rchl avatar Oct 12 '21 06:10 rchl

any updates?

abdulhadi-lababidi avatar Nov 01 '22 18:11 abdulhadi-lababidi

Hello, appreciate the work being done here. I think this should be noted on this documentation page. Thanks! https://vue-i18n.intlify.dev/guide/integrations/nuxt3

mcpeakdb avatar Nov 07 '23 17:11 mcpeakdb