Lit — это современный фреймворк для создания веб-компонентов, который строится на стандарте Custom Elements и Shadow DOM. Одной из ключевых особенностей является поддержка изоморфного рендеринга, что позволяет использовать одни и те же компоненты как на стороне клиента, так и на сервере. Изоморфный код улучшает производительность загрузки страниц, обеспечивает SEO-дружественность и упрощает управление состоянием приложения.
Изоморфный подход требует, чтобы компоненты были
самодостаточными, не зависели от прямого доступа к DOM
во время рендеринга на сервере и могли корректно сериализовать своё
состояние для клиента. В Lit для этого используется концепция реактивных
свойств и декларативного рендеринга через шаблонную функцию
html.
Универсальные компоненты в Lit создаются с соблюдением следующих принципов:
Изоляция состояния Каждое свойство компонента
объявляется с использованием декоратора @property или
статического объекта properties. Это позволяет Lit
автоматически отслеживать изменения и обновлять DOM без прямых
мутаций.
import { LitElement, html, css } from 'lit';
import { property } from 'lit/decorators.js';
class UserCard extends LitElement {
static styles = css`
.card { border: 1px solid #ccc; padding: 16px; border-radius: 8px; }
`;
@property({ type: String }) name = '';
@property({ type: Number }) age = 0;
render() {
return html`
<div class="card">
<p>Имя: ${this.name}</p>
<p>Возраст: ${this.age}</p>
</div>
`;
}
}
customElements.define('user-card', UserCard);Декларативный рендеринг Рендеринг происходит
через функцию html, которая поддерживает выражения и
директивы. Это позволяет легко интегрировать серверный рендеринг и
управлять динамическим контентом.
Отделение логики и представления Любые вычисления или асинхронные операции выносятся в методы или геттеры. Это делает компонент независимым от среды выполнения и обеспечивает корректный SSR.
Lit поддерживает работу с асинхронными источниками данных через реактивные свойства и специальные директивы. Для изоморфного рендеринга важно, чтобы компонент мог отдавать состояние при рендеринге на сервере, а затем корректно обновляться на клиенте.
Пример асинхронного компонента с серверной подготовкой данных:
import { LitElement, html } from 'lit';
import { property } from 'lit/decorators.js';
class AsyncUser extends LitElement {
@property({ type: Object }) user = null;
async connectedCallback() {
super.connectedCallback();
if (!this.user) {
this.user = await fetch('https://api.example.com/user/1')
.then(res => res.json());
}
}
render() {
if (!this.user) return html`<p>Загрузка...</p>`;
return html`
<div>
<h2>${this.user.name}</h2>
<p>Email: ${this.user.email}</p>
</div>
`;
}
}
customElements.define('async-user', AsyncUser);
При серверном рендеринге можно использовать предварительное получение данных и передавать их через свойства, исключая необходимость дополнительных запросов на клиенте.
repeat — для рендеринга списков с
минимальными затратами ресурсов, особенно важно при серверном рендеринге
больших массивов. ifDefined — для
безопасного отображения неопределённых значений.
asyncAppend / asyncReplace —
для интеграции с асинхронными источниками данных и плавного обновления
DOM без перерисовки всей страницы.
Использование директив позволяет компонентам оставаться реактивными и универсальными, независимо от среды выполнения.
Для универсальных компонентов критично корректное использование
стилей. Lit позволяет инкапсулировать стили через статическое свойство
styles, что исключает конфликты с внешними CSS. Shadow DOM
обеспечивает изоляцию, но при SSR иногда требуется использование
ShadyCSS для поддержки старых браузеров.
static styles = css`
:host {
display: block;
font-family: Arial, sans-serif;
}
.highlight {
color: var(--primary-color, blue);
}
`;
Стили могут быть динамическими и зависеть от свойств компонента, что особенно полезно для темизации и адаптивного интерфейса.
Lit автоматически минимизирует количество обновлений DOM через сравнение шаблонов и реактивных свойств. Для изоморфного кода важно:
render.guard для предотвращения
лишних вычислений.Это позволяет создавать высокопроизводительные компоненты, которые одинаково эффективно работают на сервере и клиенте.
Lit легко интегрируется с Next.js, Astro, Vite и другими изоморфными решениями. Универсальные компоненты могут быть:
Такой подход обеспечивает согласованное поведение приложения, улучшает SEO и ускоряет первую отрисовку страницы.
css обеспечивают изоляцию
и предсказуемость внешнего вида.Использование этих принципов позволяет строить масштабируемые, производительные и универсальные интерфейсы, которые одинаково корректно работают в любой среде выполнения.