Comparativo entre Frameworks
Interfaces Reativas em Tempo Real
Python / Django Channels / WebSocket
SPAs sem JavaScript, sem API REST
HTML over the Wire — interfaces reativas sem JavaScript no frontend
O HTML é renderizado no servidor e enviado ao cliente. Toda a lógica fica no backend.
Usa WebSockets ou AJAX para manter comunicação em tempo real entre cliente e servidor.
O desenvolvedor escreve apenas na linguagem do backend. O framework cuida do JS automaticamente.
Elixir / Erlang VM (BEAM)
O Pioneiro — criado por Chris McCord em 2019
Destaques:
| Métrica | Valor |
|---|---|
| ~25k | LiveViews simultâneos por 1GB de RAM |
| v1.1 | Versão atual com Colocated Hooks |
| 40kb | Consumo base por conexão WebSocket |
PHP / Laravel
Criado por Caleb Porzio — integração profunda com o ecossistema Laravel
Destaques:
| Métrica | Valor |
|---|---|
| v4 | Versão mais recente com single-file components |
| AJAX | Comunicação via HTTP (não WebSocket) |
| 40k+ | Desenvolvedores na comunidade |
Python / Django Channels
Criado por Andros Fenollosa — SPAs em tempo real com Python puro, sem JavaScript
Sobre o Criador:
Passo 1: Instalar os pacotes necessários
Pré-requisitos:
Opção A: Sem Redis (testes)
pip install django-liveview channels daphne
# ^^^^^^^^^^^^^^^^
# (destaque vermelho)
Opção B: Com Redis (recomendado para produção)
pip install django-liveview channels channels-redis daphne redis
# ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^
# (destaque vermelho) (destaque amarelo) (destaque amarelo)
Iniciar o Redis:
redis-server
ou via Docker:
docker run -d -p 6379:6379 redis:alpine
Passo 2: Configurar o Django para usar ASGI e WebSockets
# settings.py
INSTALLED_APPS = [
"daphne", # Servidor ASGI
"channels", # Django Channels
"liveview", # Django LiveView
"app", # Sua app Django
]
ASGI_APPLICATION = "myproject.asgi.application"
| Configuração | Descrição |
|---|---|
"daphne" |
Servidor ASGI — deve ser o primeiro app. Substitui o WSGI e habilita WebSockets. |
"channels" |
Django Channels — estende o Django para suportar protocolos além de HTTP. |
"liveview" |
Django LiveView — o framework que fornece handlers, routing e assets JS. |
ASGI_APPLICATION |
Aponta para o arquivo asgi.py do projeto. Define o ponto de entrada assíncrono. |
CHANNEL_LAYERS |
Configura a camada de comunicação: InMemoryChannelLayer (testes) ou RedisChannelLayer (produção). |
Passo 3: Configurar o roteamento ASGI (HTTP + WebSocket)
# myproject/asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import \ # <-- destaque: websocket
AllowedHostsOriginValidator
from liveview.routing import get_liveview_urlpatterns
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AllowedHostsOriginValidator( # <-- destaque: websocket
AuthMiddlewareStack(
URLRouter(
get_liveview_urlpatterns()
)
)
),
})
| Componente | Descrição |
|---|---|
ProtocolTypeRouter |
Roteador principal: direciona HTTP para Django e WebSocket para Channels. |
AllowedHostsOriginValidator |
Segurança: verifica se a origem do WS está em ALLOWED_HOSTS. |
AuthMiddlewareStack |
Autenticação: o consumer terá acesso ao user autenticado. |
URLRouter |
Roteamento de URLs para WebSocket, similar ao urlpatterns. |
get_liveview_urlpatterns() |
Configura automaticamente o endpoint /ws/liveview/. |
Passo 4 e 5: Criar o template base e o handler Python
{% load static %}
{% load liveview %} <!-- destaque: load liveview -->
<!DOCTYPE html>
<html lang="en" data-room="{% liveview_room_uuid %}"> <!-- destaque: data-room -->
<head>
<meta charset="UTF-8">
<title>{% block title %}My Site{% endblock %}</title>
</head>
<body data-controller="page">
{% block content %}{% endblock %}
<script src="{% static 'liveview/liveview.min.js' %}"
defer></script>
</body></html>
from liveview import liveview_handler, send # destaque: liveview_handler, send
from django.template.loader import render_to_string
@liveview_handler("say_hello") # destaque: liveview_handler
def say_hello(consumer, content): # destaque: consumer
name = content.get("form", {}).get("name", "World")
html = render_to_string(
"hello_message.html",
{"message": f"Hello, {name}!"},
)
send(consumer, { # destaque: send, consumer
"target": "#greeting",
"html": html,
})
Legenda:
load liveview — template tags do LiveViewdata-room — UUID único por página (sala WS)liveview_handler / consumer / send — API principalPasso 6 e 7: Template da página, URLs e rodar o servidor
{% extends "base.html" %}
{% block content %}
<form>
<input type="text" name="name"
placeholder="Enter your name">
<button
data-liveview-function="say_hello"
data-action="click->page#run">
Say Hello
</button>
<div id="greeting">
<h1>Hello, World!</h1>
</div>
</form>
{% endblock %}
| Atributo | Descrição |
|---|---|
data-liveview-function="say_hello" |
Qual handler Python chamar |
data-action="click->page#run" |
Evento click -> controller page -> método run |
id="greeting" |
Alvo do target: "#greeting" no handler |
python manage.py migrate # Criar tabelas
python manage.py collectstatic # Copiar JS do LiveView
python manage.py runserver # Iniciar com Daphne (ASGI)
| Característica | Phoenix LiveView (Elixir) | Laravel Livewire (PHP) | Django LiveView (Python) |
|---|---|---|---|
| Criador | Chris McCord | Caleb Porzio | Andros Fenollosa |
| Protocolo | WebSocket + LongPolling | AJAX (HTTP) | WebSocket |
| Renderização | Server (HEEx) | Server (Blade) | Server (Django Templates) |
| Stateful | Sim | Sim | Sim |
| Change Tracking / Diffs | Avançado | Parcial | Não |
| SPA sem API | Sim | Não é SPA | Sim |
| Upload de Arquivos | Nativo | Nativo | Não documentado |
| Componentes Reutiliz. | LiveComponent | Livewire Comp. | ~ Via templates |
| Validação de Forms | Tempo real | Tempo real | ~ Via eventos |
| Reconexão Automática | Sim | N/A (HTTP) | Exp. Backoff |
| Maturidade | Alta (2019, v1.1) | Alta (2020, v4) | Emergente (v2.1) |
Todos os três renderizam HTML no backend e enviam ao cliente, eliminando a necessidade de frameworks JavaScript como React ou Vue.
O desenvolvedor escreve apenas na linguagem do servidor (Elixir, PHP ou Python). O JavaScript é gerado automaticamente pelo framework.
Atualizações em tempo real na interface sem o desenvolvedor precisar escrever código JavaScript manualmente.
Mantêm o estado da conexão no lado do servidor, permitindo interações complexas e persistentes durante a sessão.
Todos seguem o padrão 'HTML over the Wire', que traz a lógica de UI para o servidor e reduz a complexidade do frontend.
Aplicações de alta concorrência, real-time intensivo, chat, dashboards ao vivo, sistemas distribuídos. Ideal quando escalabilidade é prioridade.
Aplicações Laravel existentes que precisam de interatividade. CRUDs dinâmicos, formulários complexos, painéis admin. Ideal para quem já está no ecossistema Laravel.
Projetos Django que precisam de real-time sem adotar frontend separado. SPAs simples, protótipos rápidos, equipes que dominam Python. Ideal para quem quer simplicidade.
Oportunidades de melhoria comparado ao Phoenix LiveView e Laravel Livewire
Envia o HTML completo do fragmento. Phoenix envia apenas os bytes que mudaram, reduzindo o tráfego drasticamente.
Não há documentação oficial sobre upload via WebSocket. Phoenix e Livewire têm upload nativo com preview em tempo real.
Sem equivalente ao mix phx.gen.live do Phoenix que gera CRUD completo com LiveView automaticamente.
Apenas WebSocket. Se a conexão WS não for possível, não há fallback. Phoenix oferece LongPolling como alternativa.
Sem LiveComponents com estado próprio como no Phoenix. Reutilização de UI é feita via templates Django tradicionais.
Projeto mantido por um único desenvolvedor. Comunidade menor comparada a Phoenix (25k GitHub stars) e Livewire (40k devs).
Referência: django-liveview.andros.dev