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

Apple phone version @ios13.4 ,the safari browser cann't open the page translated with vue-i18n, the page appears white screen, however phones lower than version 13.4 are normal;

Open gt1024 opened this issue 5 years ago • 9 comments

vue & vue-i18n version

ex: ^2.5.2, 8.16.0

Reproduction Link

Steps to reproduce

  1. IOS mobile phone [email protected] , when safari browser opens the page translated by vue-i18n, prompting “A problem repeatedly occurred on ”***, the page is blank.IOS version < 13.4 work well ;also android phone works well;
  2. I tried to find that it is normal when the number of translation resource file items is around 3000; However, my translation resource file items are more than 10,000;

What is Expected?

How can i solve ?

What is actually happening?

gt1024 avatar Apr 01 '20 02:04 gt1024

微信图片_20200401105728 微信图片_20200401110137

gt1024 avatar Apr 01 '20 03:04 gt1024

However, my translation resource file items are more than 10,000;

Does the issue happen if you reduced the number of translations into 100 or around ? Could you create a minimum repro?

exoego avatar Apr 18 '20 11:04 exoego

Up to 5000 translation items. Maybe related to memory. Finally, I solved it by Object.freeze(); Freeze the value in memory. const locales = Object.freeze({ en: { ...enLocale }, zh: { ...zhLocale } }) In a large data object, when you are sure that it does not need to be changed, you can freeze () it, which can greatly increase performance.

gt1024 avatar Apr 18 '20 13:04 gt1024

+1 We have the same exact problem in our app right now. We have over 12000 lines and Vue i18n crashes. We tried with 6000 translations and worked.

poblouin avatar Apr 24 '20 18:04 poblouin

Thanks for reporting. It sounds like performance problem when locale have thousands keys on mobile devices. There might be a room for optimization in vue-i18n, but I think it is difficult to support sooo-many keys on any environments.

How about to mention using Object.freeze in document for performance optimization, and close the issue ?

exoego avatar Apr 25 '20 08:04 exoego

@exoego The Object.freeze didn't work for us, I don't think you should add that to the documentation since it might not be a solution that fits all.

With some more tests on our side, we realized that our app was crashing before calling new VueI18n(). We create the config object with the translations the line before initializing VueI18n and it is crashing there. We are still exploring options, but so far we ended up chunking our translations and put a setTimeout inside a forEach to delay our VueI18n initialization a bit.

iOS 13.4 have this is its release notes: Reduced the amount of memory used by JavaScript, including for non-web clients.. I think this is the real problem here. It happens that VueI18n with a lot of translations uses a lot of JS memory. Maybe there is a bit of optimizations that could be done on your side, but ultimately the problem could happen with any library that uses a high amount of memory 🤷‍♂️

poblouin avatar Apr 25 '20 12:04 poblouin

tl;dr: change

i18n.setLocaleMessage(lang, messages);

to

i18n.setLocaleMessage(lang, Object.freeze(messages))

It seems that the reason safari can't handle 5000+ keys at once is because they are reactive properties in the vue-i18n.

Upd.: as pointed out below, chrome has same issue, I confirmed that on my device as well.

Upd.2: chunking keys by 1000 instead of Object.freeze worked locally, but did not work after webpack compilation (dies on 3000+ keys even when chunked, even with 2 seconds setTimeout between merges)

Upd.3: wow, this Object.freeze() seems to boost page performance dramatically...

klesun avatar Jun 10 '20 12:06 klesun

In our case we needed to change this:

i18n.setLocaleMessage(lang, messages);

to this to make it work:

const CHUNK_SIZE = 1000;
const keys = Object.keys(messages);
for (let i = 0; i < keys.length; i += CHUNK_SIZE) {
    const chunk = {};
    for (const key of keys.slice(i, i + CHUNK_SIZE)) {
        chunk[key] = messages[key];
    }
    i18n.mergeLocaleMessage(lang, chunk);
}

Our guess is that the reason safari can't handle 5000+ keys at once is because they are reactive properties in the vue-i18n.

Just to be more specific, it's not only Safari, the crash occurs on any browsers that are based on webkit i.e. all major browsers on iOS

poblouin avatar Jun 10 '20 13:06 poblouin

@exoego

https://developer.apple.com/documentation/safari-release-notes/safari-13-release-notes image

https://en.wikipedia.org/wiki/Safari_version_history#Safari_13_2 image

Not sure the reduce js memory patch is shipped with Safari 13 or Safari13.1 depends on iOS13 or iOS13.4.

Maybe need to optimize by code.

zl7261 avatar Jul 08 '20 06:07 zl7261