refactor(i18n): optimize translation loading and initialization
- Updated ensureTranslationsLoaded function to prevent duplicate requests by caching loaded translations and managing loading promises. - Simplified translation preloading on app startup to only load essential namespaces for the current language. - Adjusted useTranslationPreloader hook to avoid multiple requests for translations and ensure efficient loading state management.
This commit is contained in:
@@ -12,6 +12,10 @@ const ESSENTIAL_NAMESPACES = [
|
||||
'settings',
|
||||
];
|
||||
|
||||
// Cache to track loaded translations and prevent duplicate requests
|
||||
const loadedTranslations = new Set<string>();
|
||||
const loadingPromises = new Map<string, Promise<any>>();
|
||||
|
||||
i18n
|
||||
.use(HttpApi)
|
||||
.use(initReactI18next)
|
||||
@@ -37,33 +41,67 @@ i18n
|
||||
});
|
||||
|
||||
// Utility function to ensure translations are loaded
|
||||
export const ensureTranslationsLoaded = async (namespaces: string[] = ESSENTIAL_NAMESPACES) => {
|
||||
const currentLang = i18n.language || 'en';
|
||||
|
||||
export const ensureTranslationsLoaded = async (
|
||||
namespaces: string[] = ESSENTIAL_NAMESPACES,
|
||||
languages: string[] = [i18n.language || 'en']
|
||||
) => {
|
||||
try {
|
||||
// Load all essential namespaces for the current language
|
||||
await Promise.all(
|
||||
namespaces.map(ns =>
|
||||
i18n.loadNamespaces(ns).catch(() => {
|
||||
logger.error(`Failed to load namespace: ${ns}`);
|
||||
})
|
||||
)
|
||||
);
|
||||
const loadPromises: Promise<any>[] = [];
|
||||
|
||||
// Also preload for other languages to prevent delays on language switch
|
||||
const otherLangs = ['en', 'es', 'pt', 'alb', 'de'].filter(lang => lang !== currentLang);
|
||||
await Promise.all(
|
||||
otherLangs.map(lang =>
|
||||
Promise.all(
|
||||
namespaces.map(ns =>
|
||||
i18n.loadNamespaces(ns).catch(() => {
|
||||
logger.error(`Failed to load namespace: ${ns}`);
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
for (const lang of languages) {
|
||||
for (const ns of namespaces) {
|
||||
const key = `${lang}:${ns}`;
|
||||
|
||||
// Skip if already loaded
|
||||
if (loadedTranslations.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if already loading
|
||||
if (loadingPromises.has(key)) {
|
||||
loadPromises.push(loadingPromises.get(key)!);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create loading promise
|
||||
const loadingPromise = new Promise<void>((resolve, reject) => {
|
||||
// Switch to the target language temporarily if needed
|
||||
const currentLang = i18n.language;
|
||||
const shouldSwitchLang = currentLang !== lang;
|
||||
|
||||
const loadForLanguage = async () => {
|
||||
try {
|
||||
if (shouldSwitchLang) {
|
||||
await i18n.changeLanguage(lang);
|
||||
}
|
||||
|
||||
await i18n.loadNamespaces(ns);
|
||||
|
||||
// Switch back to original language if we changed it
|
||||
if (shouldSwitchLang && currentLang) {
|
||||
await i18n.changeLanguage(currentLang);
|
||||
}
|
||||
|
||||
loadedTranslations.add(key);
|
||||
resolve();
|
||||
} catch (error) {
|
||||
logger.error(`Failed to load namespace: ${ns} for language: ${lang}`, error);
|
||||
reject(error);
|
||||
} finally {
|
||||
loadingPromises.delete(key);
|
||||
}
|
||||
};
|
||||
|
||||
loadForLanguage();
|
||||
});
|
||||
|
||||
loadingPromises.set(key, loadingPromise);
|
||||
loadPromises.push(loadingPromise);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for all loading promises to complete
|
||||
await Promise.all(loadPromises);
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error('Failed to load translations:', error);
|
||||
@@ -71,7 +109,13 @@ export const ensureTranslationsLoaded = async (namespaces: string[] = ESSENTIAL_
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize translations on app startup
|
||||
ensureTranslationsLoaded();
|
||||
// Preload essential translations for current language only on startup
|
||||
const initializeTranslations = async () => {
|
||||
const currentLang = i18n.language || 'en';
|
||||
await ensureTranslationsLoaded(ESSENTIAL_NAMESPACES, [currentLang]);
|
||||
};
|
||||
|
||||
// Initialize translations on app startup (only once)
|
||||
initializeTranslations();
|
||||
|
||||
export default i18n;
|
||||
|
||||
Reference in New Issue
Block a user