Server-Side Rendering (SSR) в контексте Riot.js позволяет рендерить компоненты на сервере до того, как они будут отправлены клиенту. Это повышает производительность загрузки страницы, улучшает SEO и снижает нагрузку на клиентскую часть приложения.
Для настройки SSR потребуется Node.js и пакет riot.
Начальная установка осуществляется через npm:
npm install riot express @riotjs/ssr
Создается базовая структура проекта:
project/
├─ src/
│ ├─ components/
│ │ └─ App.riot
│ └─ server.js
├─ package.json
└─ index.html
Riot-компоненты имеют расширение .riot и включают три
блока: template, script,
style. Например, основной компонент
App.riot:
<app>
<h1>{ opts.title }</h1>
<p>{ message }</p>
<script>
export default {
message: 'Привет, SSR с Riot.js!'
}
</script>
<style>
h1 { color: #2c3e50; }
p { font-size: 16px; }
</style>
</app>
opts – объект с параметрами, передаваемыми компоненту
при инициализации.export default – описывает состояние компонента.Для SSR используется модуль @riotjs/ssr. Основная идея
заключается в том, чтобы компилировать компонент в HTML на сервере и
отправлять его клиенту.
Пример server.js:
import express from 'express'
import { render } from '@riotjs/ssr'
import App from './components/App.riot'
const app = express()
app.get('/', async (req, res) => {
const html = await render(App, { title: 'Главная страница' })
res.send(`
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Riot SSR</title>
</head>
<body>
${html}
<script type="module" src="/client.js"></script>
</body>
</html>
`)
})
app.listen(3000, () => console.log('Server started on http://localhost:3000'))
render(App, { title: '...' }) – рендерит компонент
App в HTML с указанными опциями.html уже содержит готовую разметку для
страницы.После SSR компонент должен быть “гидрирован” на клиенте, чтобы работали интерактивные функции:
import { component } from 'riot'
import App from './components/App.riot'
component(App)(document.querySelector('app'))
component(App) создаёт экземпляр компонента.document.querySelector('app'))
позволяет сохранить серверную разметку и подключить клиентскую логику
без перерисовки.Для сложных приложений данные часто подгружаются на сервере перед рендерингом:
app.get('/users', async (req, res) => {
const users = await fetchUsersFromDB()
const html = await render(App, { title: 'Пользователи', users })
res.send(html)
})
fetchUsersFromDB – асинхронная функция, возвращающая
данные.opts позволяет компоненту
использовать их сразу при рендеринге на сервере.Riot.js не включает встроенный роутер, но SSR совместим с любым серверным маршрутизатором, например Express. Маршрутизация осуществляется на сервере:
app.get('/:page', async (req, res) => {
const page = req.params.page
const html = await render(App, { title: `Страница ${page}` })
res.send(html)
})
Для повышения производительности SSR компонентов рекомендуется:
Пример простого кеширования:
const cache = {}
app.get('/news', async (req, res) => {
if (cache.news) {
return res.send(cache.news)
}
const newsData = await fetchNews()
const html = await render(App, { title: 'Новости', news: newsData })
cache.news = html
res.send(html)
})
.riot
автоматически включаются в HTML при SSR.window или document,
требуют проверки на сервере.Server-Side Rendering в Riot.js обеспечивает быструю загрузку страниц, улучшает SEO и позволяет создавать гибридные приложения, где сервер отвечает за начальный рендеринг, а клиент – за интерактивность. Настройка SSR требует точной организации компонентов и их гидрации на клиенте, а также правильной работы с асинхронными данными и маршрутизацией.