From b8b333c228ba6b1002a2430112ee67cdaeeab819 Mon Sep 17 00:00:00 2001 From: Andros Fenollosa Date: Fri, 26 Dec 2025 19:48:29 +0100 Subject: [PATCH] Improve home page with benchmarks and reorganized content - Move key features section to top with emojis for better visibility - Add benchmark response time graph from django-interactive-frameworks-benchmark - Include technology comparison table (WebSocket vs AJAX vs HTTP) - Add data transfer column to performance table - Simplify explanation of differences using clear analogies - Fix numbered list continuity issue with images - Change final section to "Ready to start?" for better call-to-action --- assets/img/benchmark-response-time.webp | Bin 0 -> 49276 bytes one.org | 112 ++++++++++++++++-------- 2 files changed, 75 insertions(+), 37 deletions(-) create mode 100644 assets/img/benchmark-response-time.webp diff --git a/assets/img/benchmark-response-time.webp b/assets/img/benchmark-response-time.webp new file mode 100644 index 0000000000000000000000000000000000000000..536b356b195a21780bbedee49eee5700d4bf21f6 GIT binary patch literal 49276 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

ceHhD9dvfl9!g3O$gU$k;^ik_NzXg`J zuY2hXOf!2*NJ_hyoc!_xBKtURF?RIxRE*Taq>b*~l(N`%$t8ROo8Hp5ΐS|m4y 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 literal 0 HcmV?d00001 diff --git a/one.org b/one.org index ec09199..5ae13ef 100644 --- a/one.org +++ b/one.org @@ -7,46 +7,13 @@ :NAVIGATOR-ACTIVE: home :END: -** What is HTML over the Wire? +** Build real-time SPAs with Python, not JavaScript -HTML over the Wire, or HTML over WebSockets, is a strategy for creating real-time SPAs by establishing a WebSocket connection between a client and server. It allows JavaScript to request actions (its only responsibility is to handle events) while the backend handles the business logic and renders HTML. This means you can create dynamic pages without reloading, without AJAX or APIs. This technology provides a secure, stable, and low-latency connection for real-time web applications. +Django LiveView is a framework for creating real-time, interactive web applications entirely in Python, inspired by [[https://hexdocs.pm/phoenix_live_view/][Phoenix LiveView]] and [[https://laravel-livewire.com/][Laravel Livewire]]. It is built on top of Django Channels. -#+ATTR_HTML: :class center-block image image--home -[[#/img/step-1.avif][Architecture send]] +Build rich, dynamic user experiences with server-rendered HTML without writing a single line of JavaScript. Perfect for Django developers who want real-time features without the complexity of a separate frontend framework. -#+ATTR_HTML: :class center-block image image--home -[[#/img/step-2.avif][Architecture receive]] - -** What is Django LiveView? 🚀 - -Django LiveView is a framework for creating real-time, interactive web applications entirely in Python 🐍, inspired by [[https://hexdocs.pm/phoenix_live_view/][Phoenix LiveView]] and [[https://laravel-livewire.com/][Laravel Livewire]]. It is built on top of Django Channels. - -Build rich, dynamic user experiences ✨ with server-rendered HTML without writing a single line of JavaScript. Perfect for Django developers who want real-time features ⚡ without the complexity of a separate frontend framework. - -Let's illustrate with an example. I want to print article number 2. - -1. A WebSocket connection (a channel) is established between the client and the server. - -2. JavaScript sends a message via WebSocket to the server (Django). - -#+ATTR_HTML: :class center-block image image--home -[[#/img/step-3.avif][Send string]] - -3. Django interprets the message and renders the HTML of the article through the template system and the database. - -4. Django sends the HTML to JavaScript via the channel and specifies which selector to embed it in. - -#+ATTR_HTML: :class center-block image image--home -[[#/img/step-4.avif][Send JSON]] - -5. JavaScript renders the received HTML in the indicated selector. - -#+ATTR_HTML: :class center-block image image--home -[[#/img/step-5.avif][Place HTML]] - -The same process is repeated for each action, such as clicking a button, submitting a form, etc. - -** What are your superpowers? 💪 +** Key features - 🎯 **Create SPAs without using APIs**: No REST or GraphQL needed - 🎨 **Uses Django's template system** to render the frontend (without JavaScript frameworks) @@ -60,6 +27,77 @@ The same process is repeated for each action, such as clicking a button, submitt - 📡 **Broadcast support** for multi-user real-time updates - 🔐 **Middleware system** for authentication and authorization +** Why Django LiveView? + +*** Performance that speaks for itself + +[[https://github.com/tanrax/django-interactive-frameworks-benchmark][Benchmarks]] show Django LiveView delivers the fastest response times among Django interactive frameworks: + +#+ATTR_HTML: :class center-block image image--benchmark +[[#/img/benchmark-response-time.webp][Response Time Comparison]] + +| Framework | Technology | Response Time | Data Transfer | Use Case | +|-----------+------------+---------------+---------------|----------| +| **LiveView** | WebSockets | **9.35ms** | 450 bytes | Real-time dashboards, collaborative apps | +| HTMX | AJAX | 16.48ms | ~37 KB | Modern UX with minimal JavaScript | +| Unicorn | AJAX | 26.76ms | ~71 KB | Complex forms with reactive state | +| SSR | POST + redirect | 47.25ms | ~8.5 KB | SEO-critical pages, traditional CRUD | + +Django LiveView is approximately **43% faster than HTMX** and **80% faster than traditional SSR** through persistent WebSocket connectivity. + +*** Technology Comparison + +| Feature | LiveView | SSR | HTMX | Unicorn | +|---------+----------+-----+------+---------| +| **Transport** | WebSocket | HTTP | AJAX | AJAX | +| **Update Type** | Real-time | Full reload | Partial | Reactive | +| **Multi-user** | ✅ Broadcast | ❌ | ❌ | ❌ | +| **Infrastructure** | Redis + Channels | Django only | Django only | Django only | +| **Page Reload** | ❌ No | ✅ Yes | ❌ No | ❌ No | + +*** What makes it different? + +The key difference is the connection model: + +**Django LiveView** uses a persistent WebSocket connection that stays open between the client and server. This allows bidirectional, real-time communication with minimal latency. Think of it like a phone call: once connected, both sides can talk instantly. + +**HTMX** sends a new HTTP request for each user interaction and updates only part of the page. It's like sending text messages: you send a message, wait for a response, then repeat. + +**Traditional SSR** reloads the entire page with each interaction through a POST request followed by a redirect. It's like hanging up and calling back every time you want to say something. + +#+ATTR_HTML: :class center-block image image--home +[[#/img/step-1.avif][Architecture send]] + +#+ATTR_HTML: :class center-block image image--home +[[#/img/step-2.avif][Architecture receive]] + +** How does it work? + +Let's illustrate with an example: displaying article number 2. + +1. [@1] A WebSocket connection (a channel) is established between the client and the server. + +2. [@2] JavaScript sends a message via WebSocket to the server (Django). + + #+ATTR_HTML: :class center-block image image--home + [[#/img/step-3.avif][Send string]] + +3. [@3] Django interprets the message and renders the HTML of the article through the template system and the database. + +4. [@4] Django sends the HTML to JavaScript via the channel and specifies which selector to embed it in. + + #+ATTR_HTML: :class center-block image image--home + [[#/img/step-4.avif][Send JSON]] + +5. [@5] JavaScript renders the received HTML in the indicated selector. + + #+ATTR_HTML: :class center-block image image--home + [[#/img/step-5.avif][Place HTML]] + +The same process is repeated for each action: clicking a button, submitting a form, navigating, etc. + +** Ready to start? + Are you ready to create your first real-time SPA? Let's go to the [[#/quick-start/][Quick start]]. * Install