Ленивая загрузка переводов (lazy loading translations) — важная техника при работе с многоязычными приложениями на Vue.js, позволяющая существенно уменьшить первоначальный размер бандла и ускорить старт приложения. Основная идея заключается в том, чтобы загружать языковые файлы только тогда, когда они действительно нужны, а не включать все переводы сразу.
Переводы обычно хранятся в виде отдельных файлов JSON. Для каждого языка создается свой файл, например:
// locales/en.json
{
"greeting": "Hello",
"farewell": "Goodbye"
}
// locales/ru.json
{
"greeting": "Привет",
"farewell": "До свидания"
}
При традиционном подходе эти файлы импортируются в главный файл i18n при старте приложения:
import { createI18n } from 'vue-i18n';
import en from './locales/en.json';
import ru from './locales/ru.json';
const i18n = createI18n({
locale: 'en',
messages: { en, ru },
});
Проблема такого подхода — все языки сразу включаются в бандл, что увеличивает размер загрузки. Для крупных проектов это становится критичным.
Vue I18n (v9 и выше) поддерживает динамический импорт сообщений. Основной механизм выглядит так:
import { createI18n } from 'vue-i18n';
const i18n = createI18n({
legacy: false,
locale: 'en',
messages: {} // изначально пустой объект
});
async function loadLocaleMessages(locale) {
if (!i18n.global.availableLocales.includes(locale)) {
const messages = await import(`./locales/${locale}.json`);
i18n.global.setLocaleMessage(locale, messages.default);
}
i18n.global.locale.value = locale;
}
import() — динамический импорт, который Webpack или
Vite преобразует в отдельный чанк.i18n.global.setLocaleMessage() — добавляет загруженные
сообщения в i18n.i18n.global.locale.value — переключает текущий
язык.Часто перевод загружается при смене маршрута, если разные маршруты требуют разные локали:
import router from './router';
import i18n from './i18n';
router.beforeEach(async (to, from, next) => {
const locale = to.params.lang || 'en';
await loadLocaleMessages(locale);
next();
});
to.params.lang — параметр языка из URL, например
/ru/home.Чтобы избежать повторной загрузки одного и того же языка, стоит
проверять наличие локали в availableLocales:
if (!i18n.global.availableLocales.includes(locale)) {
const messages = await import(`./locales/${locale}.json`);
i18n.global.setLocaleMessage(locale, messages.default);
}
Таким образом, динамический импорт срабатывает только один раз на каждый язык.
locales/
├─ en/
│ ├─ common.json
│ ├─ dashboard.json
│ └─ profile.json
└─ ru/
├─ common.json
├─ dashboard.json
└─ profile.json
Загрузка модуля при необходимости:
async function loadModuleLocale(locale, module) {
const messages = await import(`./locales/${locale}/${module}.json`);
i18n.global.mergeLocaleMessage(locale, messages.default);
}
mergeLocaleMessage() объединяет новые сообщения с уже
существующими.Предзагрузка при определенных событиях: Иногда полезно загружать язык заранее, например, при наведении на кнопку смены языка, чтобы ускорить реакцию интерфейса.
Совмещение с кешированием в localStorage: Можно
сохранять уже загруженные переводы в localStorage, чтобы
при повторном визите не делать дополнительный запрос.
Ленивая загрузка переводов является стандартной практикой для крупных Vue.js приложений и существенно повышает производительность и удобство поддержки многоязычности.