v-t rendering is slower than $t() #1712
Description
First of all, I realise Vue 2 is EOL and this repo is not actively maintained, but I feel as though this issue needs a fix and we are happy to do so, but just wanted some guidance and to confirm this is something that can be fixed and released still @kazupon
Ever since the changes made to fix this issue #450 the v-t
directive it massively slower than $t()
and it becomes more noticeable as your translation file grows.
This is because v-t
is cloning the current locale messages into each element that uses the directive, so as you get more messages in your translation file, this operation starts to take a lot of time to copy all the messages. There is also a memory overhead for this approach that is not ideal.
It becomes extremely noticeable if you're rendering multiple translations per item using v-t
in a for loop.
Relevant code:
- https://github.com/kazupon/vue-i18n/blob/v8.x/src/directive.js#L82
- https://github.com/kazupon/vue-i18n/blob/v8.x/src/index.js#L796
Expected behavior
v-t
is expected to be more performant based on the documentation (https://kazupon.github.io/vue-i18n/guide/directive.html#pros-2).
But really the expected behaviour I would say is that it doesn't copy the entire active locale messages and renders in a similar time to $t()
as it has the benefit of being cached.
Reproduction
https://stackblitz.com/edit/vitejs-vite-92c8pm
This is rendering with v-t and $t at the same time, then will show the render time in the UI for each. If you add more items to render as part of the loop, you'll see the gap widen more and more.
Even if you have a small translation file, v-t still seems to be slower.
System Info
System:
OS: macOS 14.5
CPU: (10) arm64 Apple M1 Pro
Memory: 4.58 GB / 32.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 16.17.1
npm: 8.15.0
Browsers:
Chrome: 126.0.6478.127
Safari: 17.5
npmPackages:
vue: 2.7.12 => 2.7.12
vue-i18n: 8.28.2 => 8.28.2
Screenshot
No response
Additional context
In our app, we had a page using the v-t
directive with around ~3000 items per locale in our translation files and using v-t
to render around 400 items, the page was taking 4s to render, which performance profiling shown was all due to looseClone()
in vue-i18n
. You could suggest pagination, but swapping to $t()
instead of v-t
the page renders near instantly, so clearly this performance is fixable.
This was also raised as a discussion here -> #1650 which I replied to as well.
Validations
- Read the Contributing Guidelines
- Read the Documentation
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion
- The provided reproduction is a minimal reproducible example of the bug.