FAST Element — это современный фреймворк для создания веб-компонентов на основе стандартов Web Components. Одной из ключевых особенностей является поддержка Server-Side Rendering (SSR), которая позволяет рендерить компоненты на сервере и отправлять уже готовый HTML клиенту. SSR повышает производительность загрузки страниц, улучшает SEO и снижает время до первого рендеринга.
FAST Element использует механизм template-driven rendering. В SSR шаблон компонента компилируется в функцию, которая возвращает строку HTML. При этом сохраняется реактивность: после монтирования на клиенте компонент продолжает отслеживать изменения состояния и обновлять DOM.
import { html, FASTElement } from "@microsoft/fast-element";
class MyComponent extends FASTElement {
message = "Привет, SSR!";
}
MyComponent.template = html<MyComponent>`
<div>${x => x.message}</div>
`;
На сервере этот шаблон можно рендерить с помощью функции
renderToString, которая возвращает HTML:
import { renderToString } from "@microsoft/fast-element/server";
const htmlString = renderToString(MyComponent);
1. Минимизация шаблонов и вычислений Каждое выражение внутри шаблона выполняется при рендеринге. Для SSR важно вынести сложные вычисления из шаблона в отдельные функции или заранее вычисленные значения:
class ListComponent extends FASTElement {
items = [];
get renderedItems() {
return this.items.map(item => `<li>${item}</li>`).join("");
}
}
ListComponent.template = html<ListComponent>`
<ul>${x => x.renderedItems}</ul>
`;
Такой подход снижает нагрузку на сервер и ускоряет формирование HTML.
2. Использование статических частей шаблона Все неизменяемые части DOM должны быть вынесены в статические шаблоны. FAST Element автоматически кэширует эти куски, что сокращает повторные вычисления.
const staticTemplate = html`
<header>Заголовок страницы</header>
`;
class PageComponent extends FASTElement {}
PageComponent.template = html<PageComponent>`
${staticTemplate}
<main>${x => x.content}</main>
`;
3. Lazy-rendering и отложенная инициализация Для больших компонентов с множеством вложенных элементов можно применять ленивый рендеринг. На сервере рендерятся только критические части страницы, а остальное монтируется на клиенте:
import { html, FASTElement } from "@microsoft/fast-element";
class HeavyComponent extends FASTElement {
loaded = false;
}
HeavyComponent.template = html<HeavyComponent>`
${x => x.loaded ? html`<div>Тяжелый контент</div>` : html``}
`;
При SSR важно передавать состояние компонента с сервера на клиент. FAST Element позволяет сериализовать данные и внедрять их прямо в HTML:
const state = { items: ["a", "b", "c"] };
const htmlString = renderToString(MyComponent, { state });
<!-- В HTML можно встроить JSON -->
<script id="initial-state" type="application/json">
${JSON.stringify(state)}
</script>
На клиенте компонент может считывать этот JSON и инициализироваться без лишнего запроса к API.
Частая задача при SSR — работа с асинхронными источниками данных. В FAST Element это реализуется через промисы и async функции перед рендерингом:
async function fetchData() {
return await fetch("https://api.example.com/data").then(res => res.json());
}
const data = await fetchData();
const htmlString = renderToString(MyComponent, { data });
Для больших страниц стоит использовать параллельное получение
данных и объединять промисы с Promise.all для
сокращения времени генерации HTML.
Чтобы ускорить SSR, часто применяют кэширование готового HTML. FAST Element позволяет использовать готовые строки HTML для повторного рендеринга одинаковых страниц:
const cache = new Map();
function renderPage(props) {
const key = JSON.stringify(props);
if (cache.has(key)) return cache.get(key);
const htmlString = renderToString(MyComponent, props);
cache.set(key, htmlString);
return htmlString;
}
Кэширование особенно эффективно для страниц с небольшим количеством динамических элементов или при CDN-распределении.
После SSR компонент монтируется на клиенте. Для минимизации “гигантских патчей” DOM стоит использовать:
class OptimizedComponent extends FASTElement {
message = "Hello SSR";
// избегаем ненужной реактивности
nonReactiveValue = computeHeavyValue();
}
При SSR страницы обычно рендерятся на основе URL. FAST Element не включает роутер по умолчанию, поэтому интеграция с серверным роутером (например, Express или Fastify) осуществляется через промежуточный слой:
app.get("/page/:id", async (req, res) => {
const data = await getData(req.params.id);
const html = renderToString(MyComponent, { data });
res.send(html);
});
Такой подход позволяет генерировать разные HTML для каждого маршрута без необходимости повторного рендеринга на клиенте.
Этот подход к SSR в FAST Element сочетает скорость серверного рендеринга, эффективное управление состоянием, ленивую и кэшированную генерацию HTML и минимизацию клиентской нагрузки, что делает приложения быстрыми и отзывчивыми.