Use the full "Django LiveView" name in the README comparison tables, CLI examples, and in the implementation id exposed by run_performance_tests.py (which propagates to CSV columns and Plotly chart labels). Avoids ambiguity with Phoenix LiveView, which is referenced elsewhere in the repo.
Django Interactive Frameworks Benchmark
Performance comparison of Django's main interactive frameworks. This project implements the same alert system using six different approaches: Django LiveView (WebSocket), traditional SSR, django-htmx (AJAX), Django Unicorn (reactive components), Django Reactor (Phoenix LiveView style), and djust (Rust-powered Phoenix LiveView style). The goal is to measure and compare their real-world performance, network overhead, and user experience characteristics.
Technology Comparison
| Feature | Django LiveView (/) |
SSR (/ssr/) |
django-htmx (/htmx/) |
Unicorn (/unicorn/) |
Reactor (/reactor/) |
djust (/djust/) |
|---|---|---|---|---|---|---|
| Transport | WebSocket | HTTP | AJAX | AJAX | WebSocket | WebSocket |
| Update Type | Real-time | Full reload | Partial | Reactive | Real-time | Real-time (VDOM patches) |
| Multi-user | ✅ Broadcast | ❌ | ❌ | ❌ | ✅ Broadcast | ✅ Broadcast |
| Infrastructure | Redis + Channels | Django only | Django only | Django only | Redis + Channels | Redis + Channels + Rust |
Results Summary and Performance Conclusions
You can see the results on my blog
Run your own tests: Quick Start
docker compose up --build
Access at http://localhost:8000/ - Navigation bar switches between implementations.
Implementation Details
| Aspect | Implementation |
|---|---|
| django-htmx CSRF | <body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'> |
| Theme | <html data-theme="light"> (Bulma CSS) |
| Templates | templates/alerts/{ssr,htmx,unicorn}/ |
| Components | alerts/components/alert_list.py (Unicorn) |
| Views | All in alerts/views.py |
| Reactor | alerts/reactor_components/live.py |
| djust | alerts/djust_components/live.py |
Dependencies
- django-liveview - WebSocket reactive framework
- django-htmx
==1.22.0- HTMX middleware for Django - django-unicorn
==0.62.0- Reactive components - django-reactor
==5.3.0b0- Phoenix LiveView for Django - djust
==0.4.2- Rust-powered Phoenix LiveView-style framework for Django - Django Channels + Redis - WebSocket infrastructure
- Uvicorn - ASGI server
Technology Documentation
- Django LiveView - Official Django LiveView documentation
- HTMX - Official HTMX documentation and examples
- Django Unicorn - Complete Unicorn documentation
- Django Reactor - Phoenix LiveView but for Django
- djust - Rust-powered reactive server-side rendering for Django
- Django - Django official documentation (for SSR implementation)
Performance Testing
A fully automated benchmark drives each implementation through a headless Chromium (Playwright) and records the "Add Random Alert" round-trip. Everything runs in Docker, so results are reproducible on any machine.
How it works
- The
benchservice (seecompose.yaml+Dockerfile.bench) runs Playwright against thewebcontainer over Docker's internal network. - For every implementation: the DB is wiped via
/_bench/clear/, the page is loaded fresh, and two warmup iterations are discarded before measuring 10 real iterations. - Each iteration clicks the real "Add Random Alert" button and stops the clock when a new row actually appears in the DOM (or, for SSR, when navigation completes).
- HTTP response bodies are captured via Playwright's
response.body(); WebSocket frames are captured viapage.on("websocket"). - Results are written to a timestamped CSV. The plot script renders four comparison charts with Plotly.
Reproducing the benchmark
Start the stack and run the bench service on demand:
# 1. Bring up the app
docker compose up -d --build
# 2. Run the benchmark (uses the "bench" profile so it stays out of the default up)
docker compose --profile bench run --rm bench
# 3. Regenerate the four PNG charts from the latest CSV
docker compose --profile bench run --rm bench python generate_plotly_plots.py
The CSV lands in the project root as performance_results_YYYYMMDD_HHMMSS.csv (git-ignored). You can also filter which implementations to measure:
docker compose --profile bench run --rm bench python run_performance_tests.py --only djust "Django LiveView" --iterations 20
Scripts
| File | Purpose |
|---|---|
run_performance_tests.py |
Playwright-driven benchmark runner (entrypoint of the bench service) |
generate_plotly_plots.py |
Renders the four comparison PNGs from the most recent CSV |
Dockerfile.bench |
Playwright Python image with Plotly and Kaleido |
Troubleshooting
| Issue | Solution |
|---|---|
| Templates not updating | docker compose restart web |
| django-htmx 403 CSRF | Check hx-headers in <body> tag |
| Dark tables | Add data-theme="light" to <html> |
| Bench can't reach web | Both services must be on the same compose network; the runner uses BENCH_BASE_URL=http://web:8000 by default |
Features
| Feature | Django LiveView | SSR | django-htmx | Unicorn | Reactor | djust |
|---|---|---|---|---|---|---|
| Create alerts | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| View details | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Delete | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Notifications | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Modals | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
| Form validation | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| No page reload | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
MIT License - Reference implementation for Django web technologies