aralroca / next-translate

Next.js plugin + i18n API for Next.js 🌍 - Load page translations and use them in an easy way!
MIT License
2.65k stars 206 forks source link

Large bundle size addition for lazy loading when many translations files #1222

Open iliran11 opened 3 months ago

iliran11 commented 3 months ago

What version of this package are you using? 2.6.2 What operating system, Node.js, and npm version? Node.js. Using the pages system of next.js (not app router) What happened? I am migrating to next-translate. we have over 200 namespaces files (12 languages, 19 namespaces) When I am inspecting the bundle size, i see a rather large addition to my bundle size, due to the lazy loading.

I am using loadLocaleFrom function in the following way:

loadLocaleFrom: async (lang, ns) => {
    switch (lang) {
      case 'en':
        return import(`./public/locales/en/${ns}.json`).then((m) => m.default);
      case 'fr':
        return import(`./public/locales/fr/${ns}.json`).then((m) => m.default);
      case 'ru':
        return import(`./public/locales/ru/${ns}.json`).then((m) => m.default);
      case 'es':
        return import(`./public/locales/es/${ns}.json`).then((m) => m.default);
      case 'de':
        return import(`./public/locales/de/${ns}.json`).then((m) => m.default);
      case 'ko':
        return import(`./public/locales/ko/${ns}.json`).then((m) => m.default);
      case 'ja':
        return import(`./public/locales/ja/${ns}.json`).then((m) => m.default);
      case 'zh':
        return import(`./public/locales/zh/${ns}.json`).then((m) => m.default);
      case 'it':
        return import(`./public/locales/it/${ns}.json`).then((m) => m.default);
      case 'nl':
        return import(`./public/locales/nl/${ns}.json`).then((m) => m.default);
      case 'th':
        return import(`./public/locales/th/${ns}.json`).then((m) => m.default);
      case 'vi':
        return import(`./public/locales/vi/${ns}.json`).then((m) => m.default);
      case 'pt':
        return import(`./public/locales/pt/${ns}.json`).then((m) => m.default);
      default:
        throw new Error(`Language ${lang} is not supported`);
    }
  },

image

What did you expect to happen? No impact on bundle size. if we would want to expand to 30 languages, then it would affect the whole website.

m-sanders commented 2 months ago

This is the lazy resource lookup maps created when using a template string within import():

import(`./public/locales/en/${ns}.json`)

It is not specific to this library but to how Webpack fundamentally works. Take a look at the underlying import.meta.webpackContext behaviour:

https://webpack.js.org/api/module-variables/#importmetawebpackcontext

Webpack needs a map of all available lazy modules that match the pattern ./public/locales/en/${ns}.json. If you look in the bundle source you should see that this is an object of lazy path names to module URLs.

iliran11 commented 2 months ago

Thanks @m-sanders There are suggestions how to bypass this behavior?

It basically means the more pages i have, the more bundle size i will serve.

aralroca commented 2 months ago

@iliran11 I see i18next in your bundle, not next-translate... ?