Server-Side Rendering (SSR) позволяет предварительно рендерить
компоненты на сервере, что улучшает скорость загрузки страницы и SEO. В
контексте Lit это достигается благодаря возможности генерации HTML на
сервере с использованием методов рендеринга renderToString
из библиотеки lit/server.
Ключевым моментом является отделение логики рендеринга от клиентской интерактивности. На сервере создаётся статическая разметка, которая затем передаётся в браузер. Это уменьшает время до первого рендеринга (Time to First Paint) и делает приложение видимым даже при медленном соединении.
import { html } from 'lit';
import { renderToString } from 'lit/server';
const template = (name) => html`<h1>Привет, ${name}!</h1>`;
const htmlString = renderToString(template('Мир'));
console.log(htmlString); // <h1>Привет, Мир!</h1>
При создании SSR-приложений важно разделять три уровня:
Для гидратации используется метод hydrate из пакета
lit/experimental-hydrate. Он позволяет превратить
статический HTML в интерактивные компоненты без полного повторного
рендеринга.
import { hydrate } from 'lit/experimental-hydrate';
import './my-component.js';
hydrate(document.body);
SSR на Lit часто реализуется с помощью Node.js и Express. Сервер получает запрос, рендерит компонент в строку и возвращает готовый HTML:
import express from 'express';
import { html } from 'lit';
import { renderToString } from 'lit/server';
import './components/my-app.js';
const app = express();
app.get('/', (req, res) => {
const content = renderToString(html`<my-app></my-app>`);
res.send(`
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>SSR на Lit</title>
<script type="module" src="/client.js"></script>
</head>
<body>${content}</body>
</html>
`);
});
app.listen(3000);
Для SSR критично, чтобы состояние компонентов было сериализуемым и передавалось на клиент. Обычно используют JSON-объект, который вставляется в HTML:
const state = { user: 'Иван' };
const content = renderToString(html`
<my-app .state=${state}></my-app>
<script>window.__INITIAL_STATE__ = ${JSON.stringify(state)}</script>
`);
На клиенте состояние подхватывается при гидратации:
import './my-app.js';
import { hydrate } from 'lit/experimental-hydrate';
const state = window.__INITIAL_STATE__;
hydrate(document.body, { scope: state });
querySelector, getBoundingClientRect и события
браузера недоступны.Lit позволяет использовать асинхронные шаблоны через
until из lit/directives/until.js:
import { html } from 'lit';
import { until } from 'lit/directives/until.js';
const asyncTemplate = async () => {
const data = await fetchData();
return html`<p>${data}</p>`;
};
const template = html`${until(asyncTemplate(), html`<p>Загрузка...</p>`)};`;
На сервере это позволяет подготовить HTML с “запасным контентом”, который заменится на клиенте при доступности данных.
SSR на Lit требует чёткого разделения рендеринга, состояния и клиентской логики. Правильная организация компонентов, оптимизация загрузки и использование директив для асинхронных данных создают высокопроизводительные, SEO-дружественные приложения, способные быстро реагировать на запросы пользователя.