Lazy loading (ленивая загрузка) в Radix UI — это подход, позволяющий откладывать создание и рендеринг компонентов до момента их фактического использования. Это особенно актуально для сложных интерфейсов с множеством интерактивных элементов, таких как модальные окна, дропдауны, аккордеоны и тултипы, где рендер всех компонентов сразу приводит к увеличению времени загрузки и потребления памяти.
Radix UI предоставляет встроенные механизмы для ленивой инициализации своих компонентов, сохраняя при этом полный контроль над состоянием и анимациями.
В основе ленивой загрузки лежит отсроченная инициализация
DOM-узлов компонента. В Radix UI это реализуется через атрибут
forceMount и компонент Portal.
Основные моменты:
AnimatePresence или CSS-анимаций.import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
export function LazyDropdown() {
return (
<DropdownMenu.Root>
<DropdownMenu.Trigger>Меню</DropdownMenu.Trigger>
<DropdownMenu.Content sideOffset={5} align="start" forceMount={false}>
<DropdownMenu.Item>Пункт 1</DropdownMenu.Item>
<DropdownMenu.Item>Пункт 2</DropdownMenu.Item>
<DropdownMenu.Item>Пункт 3</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>
);
}
Разбор примера:
forceMount={false} указывает Radix UI
не рендерить содержимое до первого открытия меню.DropdownMenu.Content автоматически создаст DOM-узлы при
клике на Trigger.Диалоговые окна часто содержат тяжелые компоненты и формы. Ленивый рендер помогает экономить ресурсы и ускоряет загрузку страницы.
import * as Dialog from '@radix-ui/react-dialog';
export function LazyDialog() {
return (
<Dialog.Root>
<Dialog.Trigger>Открыть диалог</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay />
<Dialog.Content forceMount={false}>
<h2>Форма ввода</h2>
<form>
<input type="text" placeholder="Имя" />
<button type="submit">Отправить</button>
</form>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
}
Особенности:
Dialog.Content внутри Portal создается
только при первом открытии окна.FocusScope)
и клавиатурной навигацией.Для вкладок (Tabs) ленивый рендер особенно полезен, если
каждая вкладка содержит тяжелые компоненты, графики или таблицы
данных.
import * as Tabs from '@radix-ui/react-tabs';
export function LazyTabs() {
return (
<Tabs.Root defaultValue="tab1">
<Tabs.List>
<Tabs.Trigger value="tab1">Вкладка 1</Tabs.Trigger>
<Tabs.Trigger value="tab2">Вкладка 2</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="tab1" forceMount={false}>
<p>Содержимое первой вкладки</p>
</Tabs.Content>
<Tabs.Content value="tab2" forceMount={false}>
<p>Содержимое второй вкладки</p>
</Tabs.Content>
</Tabs.Root>
);
}
Ключевые моменты:
forceMount={false} позволяет уменьшить начальную
нагрузку на DOM.Radix UI предоставляет два способа управления ленивым рендером:
forceMount={false} (по умолчанию
true для некоторых компонентов) — стандартная
ленивость.Portal — позволяет
полностью отделить DOM-структуру компонента от основного дерева, что
полезно для модальных окон и тултипов.Пример с условной отрисовкой:
{isOpen && <Tooltip.Content forceMount={false}>Подсказка</Tooltip.Content>}
forceMount={false} Radix UI
гарантирует корректное управление фокусом и анимацией.Использование ленивой загрузки компонентов Radix UI позволяет:
Использование ленивой загрузки в Radix UI является мощным инструментом оптимизации интерфейсов. Он позволяет поддерживать производительность даже при сложных и насыщенных компонентами приложениях, не жертвуя удобством взаимодействия и функциональностью.