Atomico — современная библиотека для построения веб-компонентов с реактивной моделью, где особое внимание уделено производительности и модульности. Одной из ключевых задач при разработке мультиязычных приложений является эффективное управление локалями. Ленивая загрузка локалей позволяет загружать языковые пакеты по мере необходимости, снижая первоначальный размер бандла и ускоряя загрузку страницы.
Ленивая загрузка локалей строится на следующих принципах:
Эти принципы позволяют создавать приложения, где поддержка большого числа языков не влияет на скорость первичной загрузки.
Пример структуры папок для мультиязычного приложения:
src/
├─ locales/
│ ├─ en.js
│ ├─ ru.js
│ └─ es.js
├─ components/
│ └─ MyComponent.js
└─ index.js
Каждый файл локали экспортирует объект с переводами:
// locales/ru.js
export default {
greeting: "Привет",
farewell: "До свидания",
button: {
save: "Сохранить",
cancel: "Отмена"
}
};
// locales/en.js
export default {
greeting: "Hello",
farewell: "Goodbye",
button: {
save: "Save",
cancel: "Cancel"
}
};
Atomico поддерживает динамический импорт модулей, что позволяет реализовать ленивую загрузку:
import { createSignal } from "atomico";
const [locale, setLocale] = createSignal({});
async function loadLocale(lang) {
switch(lang) {
case "ru":
setLocale(await import("../locales/ru.js").then(mod => mod.default));
break;
case "en":
setLocale(await import("../locales/en.js").then(mod => mod.default));
break;
default:
setLocale(await import("../locales/en.js").then(mod => mod.default));
}
}
В этом примере при вызове loadLocale("ru") модуль
ru.js загружается асинхронно. Если язык уже был загружен,
его объект может храниться в памяти, чтобы избежать повторных
запросов.
Компоненты Atomico могут использовать сигнал локали для отображения текста:
import { c, useSignal } from "atomico";
function MyComponent() {
const locale = useSignal({});
return (
<host>
<h1>{locale.greeting}</h1>
<button>{locale.button?.save}</button>
</host>
);
}
customElements.define("my-component", c(MyComponent));
После загрузки локали с помощью loadLocale("ru")
реактивный сигнал автоматически обновит текст внутри компонента без
перезагрузки страницы.
Для поддержки переключения языков создаётся функция, которая меняет сигнал локали и вызывает повторный рендер:
const [currentLang, setCurrentLang] = createSignal("en");
async function switchLanguage(lang) {
await loadLocale(lang);
setCurrentLang(lang);
}
Использование:
<button onCl ick={() => switchLanguage("ru")}>Русский</button>
<button onCl ick={() => switchLanguage("en")}>English</button>
После нажатия кнопки компонент автоматически отображает переведённый текст.
Для уменьшения количества сетевых запросов можно хранить загруженные локали в объекте:
const localeCache = {};
async function loadLocale(lang) {
if (localeCache[lang]) {
return localeCache[lang];
}
const mod = await import(`../locales/${lang}.js`);
localeCache[lang] = mod.default;
return localeCache[lang];
}
Это позволяет:
Atomico предоставляет удобные хуки для работы с сигналами и асинхронными данными:
import { useEffect, useSignal } from "atomico";
function useLocale(lang) {
const locale = useSignal({});
useEffect(async () => {
locale.value = await loadLocale(lang);
}, [lang]);
return locale;
}
Компонент можно переписать с использованием этого хука:
function MyComponent({ lang }) {
const locale = useLocale(lang);
return (
<host>
<h1>{locale.greeting}</h1>
<button>{locale.button?.save}</button>
</host>
);
}
Теперь любое изменение свойства lang автоматически
вызывает загрузку соответствующей локали и обновление интерфейса.
Для приложений с десятками локалей рекомендуется:
import(\../locales/${lang}.js).Ленивая загрузка локалей в Atomico позволяет построить высокопроизводительные мультиязычные приложения, где текст интерфейса подгружается по требованию, сохраняя отзывчивость и минимальный размер бандла. Подход хорошо интегрируется с реактивной моделью сигналов и хуками Atomico, обеспечивая удобное и эффективное управление языками.