mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
perf: lazy-load locale files per language instead of bundling all
Split 574KB monolithic locales chunk into per-language lazy chunks: - ru: 211KB (loaded on startup as fallback) - fa: 143KB, en: 121KB, zh: 101KB (loaded on demand) Russian users save 63% bandwidth. Other languages loaded only when user switches via LanguageSwitcher.
This commit is contained in:
48
src/i18n.ts
48
src/i18n.ts
@@ -2,25 +2,36 @@ import i18n from 'i18next';
|
|||||||
import { initReactI18next } from 'react-i18next';
|
import { initReactI18next } from 'react-i18next';
|
||||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||||
|
|
||||||
import ru from './locales/ru.json';
|
const localeLoaders: Record<string, () => Promise<{ default: Record<string, string> }>> = {
|
||||||
import en from './locales/en.json';
|
ru: () => import('./locales/ru.json'),
|
||||||
import zh from './locales/zh.json';
|
en: () => import('./locales/en.json'),
|
||||||
import fa from './locales/fa.json';
|
zh: () => import('./locales/zh.json'),
|
||||||
|
fa: () => import('./locales/fa.json'),
|
||||||
const resources = {
|
|
||||||
ru: { translation: ru },
|
|
||||||
en: { translation: en },
|
|
||||||
zh: { translation: zh },
|
|
||||||
fa: { translation: fa },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SUPPORTED_LANGS = Object.keys(localeLoaders);
|
||||||
|
const FALLBACK_LNG = 'ru';
|
||||||
|
|
||||||
|
const loadedLanguages = new Set<string>();
|
||||||
|
|
||||||
|
async function loadLanguage(lng: string): Promise<void> {
|
||||||
|
if (loadedLanguages.has(lng)) return;
|
||||||
|
|
||||||
|
const loader = localeLoaders[lng];
|
||||||
|
if (!loader) return;
|
||||||
|
|
||||||
|
const mod = await loader();
|
||||||
|
i18n.addResourceBundle(lng, 'translation', mod.default, true, true);
|
||||||
|
loadedLanguages.add(lng);
|
||||||
|
}
|
||||||
|
|
||||||
i18n
|
i18n
|
||||||
.use(LanguageDetector)
|
.use(LanguageDetector)
|
||||||
.use(initReactI18next)
|
.use(initReactI18next)
|
||||||
.init({
|
.init({
|
||||||
resources,
|
fallbackLng: FALLBACK_LNG,
|
||||||
fallbackLng: 'ru',
|
supportedLngs: SUPPORTED_LANGS,
|
||||||
supportedLngs: ['ru', 'en', 'zh', 'fa'],
|
partialBundledLanguages: true,
|
||||||
|
|
||||||
detection: {
|
detection: {
|
||||||
order: ['localStorage', 'navigator'],
|
order: ['localStorage', 'navigator'],
|
||||||
@@ -37,4 +48,15 @@ i18n
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Load detected language + fallback on startup
|
||||||
|
const detectedLng = i18n.language?.split('-')[0] || FALLBACK_LNG;
|
||||||
|
const langsToLoad = [FALLBACK_LNG, ...(detectedLng !== FALLBACK_LNG ? [detectedLng] : [])];
|
||||||
|
Promise.all(langsToLoad.map(loadLanguage));
|
||||||
|
|
||||||
|
// Lazy-load on language change
|
||||||
|
i18n.on('languageChanged', (lng: string) => {
|
||||||
|
const code = lng.split('-')[0];
|
||||||
|
loadLanguage(code);
|
||||||
|
});
|
||||||
|
|
||||||
export default i18n;
|
export default i18n;
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ export default defineConfig({
|
|||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
output: {
|
output: {
|
||||||
manualChunks(id) {
|
manualChunks(id) {
|
||||||
if (id.includes('/src/locales/')) return 'locales';
|
|
||||||
if (!id.includes('node_modules')) return;
|
if (!id.includes('node_modules')) return;
|
||||||
if (
|
if (
|
||||||
id.includes('react-dom') ||
|
id.includes('react-dom') ||
|
||||||
|
|||||||
Reference in New Issue
Block a user