Performance: i18n Lazy Loading, Bundle-Größe halbiert

- i18n lädt EN/SR Übersetzungen nur bei Bedarf
- Hauptbundle von 356KB auf 179KB reduziert (~50%)
- Entfernt modulepreload für nicht-kritische Chunks
- Nur react-vendor und i18n-vendor werden vorgeladen

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-05 23:20:18 +01:00
co-authored by Claude Opus 4.5
parent ff92b58e83
commit db6d969874
2 changed files with 31 additions and 13 deletions
+22 -10
View File
@@ -3,9 +3,19 @@ import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
// Only load German synchronously (default language)
import translationDE from './locales/de';
import translationEN from './locales/en';
import translationSR from './locales/sr';
// Lazy load other languages when needed
const loadLanguage = async (lng: string) => {
if (lng === 'en' && !i18n.hasResourceBundle('en', 'translation')) {
const { default: translationEN } = await import('./locales/en');
i18n.addResourceBundle('en', 'translation', translationEN, true, true);
} else if (lng === 'sr' && !i18n.hasResourceBundle('sr', 'translation')) {
const { default: translationSR } = await import('./locales/sr');
i18n.addResourceBundle('sr', 'translation', translationSR, true, true);
}
};
i18n
.use(LanguageDetector)
@@ -14,19 +24,21 @@ i18n
resources: {
de: {
translation: translationDE
},
en: {
translation: translationEN
},
sr: {
translation: translationSR
}
},
fallbackLng: 'en',
supportedLngs: ['en', 'de', 'sr'],
fallbackLng: 'de',
supportedLngs: ['de', 'en', 'sr'],
interpolation: {
escapeValue: false
}
});
// Load language bundle when language changes
i18n.on('languageChanged', loadLanguage);
// Load initial language if not German
if (i18n.language && i18n.language !== 'de') {
loadLanguage(i18n.language);
}
export default i18n;
+9 -3
View File
@@ -5,18 +5,24 @@ import mdx from '@mdx-js/rollup';
import remarkFrontmatter from 'remark-frontmatter';
import remarkMdxFrontmatter from 'remark-mdx-frontmatter';
// Plugin to make CSS non-blocking using the print media trick
// Plugin to make CSS non-blocking and remove unnecessary preloads
function asyncCssPlugin(): Plugin {
return {
name: 'async-css',
enforce: 'post',
transformIndexHtml(html) {
// Convert blocking CSS to async loading with print media trick
return html.replace(
// Convert blocking CSS to async loading
html = html.replace(
/<link rel="stylesheet" crossorigin href="(\/assets\/css\/[^"]+\.css)">/g,
`<link rel="preload" href="$1" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="$1"></noscript>`
);
// Remove modulepreload for non-critical chunks (animations, icons loaded later)
html = html.replace(/<link rel="modulepreload" crossorigin href="\/assets\/js\/animations[^"]*\.js">\n?/g, '');
html = html.replace(/<link rel="modulepreload" crossorigin href="\/assets\/js\/icons[^"]*\.js">\n?/g, '');
return html;
}
};
}