← На главную

HTML over the wire: сервер отдаёт готовый HTML по WebSocket

12.08.2026 16:51 · hackernews

Построить SPA обычно значит взять JavaScript-фреймворк, API с JSON и два независимых кодовых базы, которые связывают контракты. Но есть другой путь: HTML over WebSockets. Сервер не отдаёт JSON, а сразу готовый HTML, клиент только ставит его в нужное место. Вся рендер-логика живёт на Back-End, на одном языке, без API и контрактов. Этот подход называют hypermedia или HTML over the wire, а транспорт определяет, насколько быстро и в обе стороны идёт общение.

Началось всё с Криса МакКорда: на ElixirConf 2019 он показал LiveView для Phoenix и за 15 минут собрал клон Twitter в реальном времени, без рендерящего JavaScript и без React, Angular или Vue. С тех пор идею подхватили в других языках. На клиенте JavaScript всё-таки есть, но он не рендерит, а открывает WebSocket-канал и вставляет полученный HTML в нужное место. Сервер сам ходит в базу, рендерит шаблон и отправляет готовую разметку. Канал остаётся открытым, поэтому сервер может пушить изменения без запроса.

У подхода есть плюсы. Один рендер-движок вместо двух. Не нужен API, JSON и прослойки. Состояние каждого клиента живёт на сервере — это противоположность stateless-подходу htmx. Есть прямой доступ к базе, настоящий real-time и broadcast: сервер может разом отправить изменения всем клиентам, поэтому чат, дашборд или мультиплеер собираются почти бесплатно. Меньше трафика и задержек: не нужно повторять TCP handshake и HTTP-заголовки на каждое действие. SPA получается с минимумом JavaScript. С SEO тоже нормально: первый HTML приходит с сервера и индексируется. А благодаря серверному экранированию попытка протащить <script> доедет до другого клиента как безобидный текст, так что XSS таким образом не пройдёт.

Минусы тоже есть. Серверу нужно больше ресурсов: под каждого клиента висит WebSocket и обычно его состояние в памяти. Горизонтальное масштабирование требует расшаривать состояние — например, в Django через Channels + ASGI-сервер + Redis. При большой физической задержке «мгновенность» страдает. Офлайн работа невозможна: при обрыве соединения сайт встаёт, нужно продумывать переподключение. И порог входа выше, чем просто подключить <script>: с LiveView-паттерном придётся разобраться.

Сейчас hypermedia-решения есть почти в каждом языке. По транспорту они делятся на WebSocket, HTTP и SSE. Среди WebSocket-вариантов — Phoenix LiveView, Django LiveView, Reactor, djust, Tetra, Blazor (Interactive Server через SignalR), Livewire 3 + Reverb. По HTTP работают django-unicorn, Hotwire и htmx. Отдельно стоит Datastar на SSE.

SSE — дешёвая альтернатива, когда поток в основном идёт от сервера к клиенту: уведомления, лента, дашборд, токены от AI-ответа. Это тот же готовый HTML, но по простому одностороннему HTTP-каналу, проще балансировать нагрузку. Ограничения: только сервер пушит, клиенту для отправки нужен отдельный HTTP-запрос, только текст без бинарных данных. htmx с SSE-расширением работает почти как LiveView: нужна только разметка вроде hx-ext="sse", а под капотом браузерный EventSource с авто-переподключением.

Правило простое: нужен двусторонний низколатентный обмен — берите WebSocket. Нужен только пуш с сервера — хватит SSE. Если достаточно обычного запроса-ответа — подойдёт htmx по HTTP. Главная мысль: отправляйте HTML вместо JSON, оставайтесь на одном языке и вычёркивайте из списка API, контракты и половину фронтенда.

Читать оригинал →