Faster Templates, Smarter Hydration: Performance Optimizations in djust 0.1.6
Why Performance Matters for Server-Side Rendering
In a world where users expect instant interactions, every millisecond counts. Traditional server-side rendering can feel sluggish compared to client-side frameworks, but it doesn't have to be that way. With djust 0.1.6, we've pushed the boundaries of what's possible with server-rendered reactive applications.
This release introduces four significant performance improvements that work together to make your djust applications faster and more memory-efficient. Let's dive into each one.
AST Optimization: 5-15% Faster Template Rendering
Every time djust renders a template, it first parses it into an Abstract Syntax Tree (AST). In previous versions, the parser would create separate nodes for each piece of static text, even when they appeared consecutively.
Consider this template fragment:
<div class="card">
<!-- User profile card -->
<span class="name">{{ user.name }}</span>
</div>
Previously, this would create multiple Text nodes and a Comment node that produce no output. Now, the new optimize_ast() function automatically:
- Merges adjacent Text nodes into a single node, reducing allocations
- Removes Comment nodes during optimization (since they produce no output)
- Recursively optimizes children in If, For, Block, and With nodes
The result? Fewer memory allocations during rendering and a 5-15% improvement in render time, with text-heavy templates seeing the biggest gains.
| Template Type | Speedup |
|---|---|
| Text-heavy templates | 10-15% |
| Mixed content | 5-10% |
| Logic-heavy templates | 2-5% |
Lazy Hydration: 20-40% Memory Reduction
Not every LiveView element needs to be interactive immediately. A dashboard might have charts below the fold that the user may never scroll to. A product page might have expandable sections that most users never open.
Lazy hydration allows you to defer WebSocket connections until they're actually needed. Instead of establishing connections for all LiveView elements on page load, you can specify when each element should "wake up."
Add the data-live-lazy attribute to any LiveView element:
<!-- Hydrate when scrolled into viewport (default) -->
<div data-live-view="comments" data-live-lazy>
<div class="skeleton">Loading comments...</div>
</div>
<!-- Hydrate on first click -->
<div data-live-view="editor" data-live-lazy="click">
<button>Click to edit</button>
</div>
<!-- Hydrate on hover -->
<div data-live-view="preview" data-live-lazy="hover">
<span>Hover for details</span>
</div>
<!-- Hydrate during browser idle time -->
<div data-live-view="analytics" data-live-lazy="idle">
Loading analytics...
</div>
Each mode serves a different use case:
| Mode | Best For |
|---|---|
viewport (default) | Below-fold content, long pages, infinite scroll |
click | Expandable sections, modals, tabbed content |
hover | Tooltips, preview cards, hover menus |
idle | Low-priority content, preloading |
For programmatic control, use the JavaScript API:
// Force hydration of a specific element
window.djust.lazyHydration.hydrateNow(element);
// Check if element is pending hydration
const isPending = window.djust.lazyHydration.isPending(element);
// Hydrate all pending elements at once
window.djust.lazyHydration.hydrateAll();
TurboNav Integration: Seamless Navigation
Single-page application navigation (like Turbo Drive or Hotwire) provides a smooth browsing experience, but it can conflict with frameworks that expect full page loads. djust 0.1.6 introduces full TurboNav compatibility.
When navigating between pages:
- Existing WebSocket connections are properly disconnected
- LiveView state is cleaned up to prevent memory leaks
- New connections are established for the incoming page's LiveView elements
- Lazy hydration state is reset for the new page
To enable TurboNav support, include the djust client script in your base template so it's available on all pages:
<!-- base.html -->
<script src="{% static 'djust/client.js' %}"></script>
A double-load guard prevents issues if the script is included multiple times, and the turbo:load event handler automatically reinitializes djust after each navigation.
Whitespace Preservation: Proper Code Formatting
When rendering code snippets or preformatted text, whitespace matters. Previous versions could inadvertently collapse or modify whitespace during VDOM patching.
djust 0.1.6 now properly preserves all whitespace inside:
<pre>elements (preformatted text)<code>elements (inline and block code)<textarea>elements (form inputs)<script>elements (inline JavaScript)<style>elements (inline CSS)
This ensures that code examples, poetry, ASCII art, and any other whitespace-sensitive content renders exactly as intended.
Bonus: Form Validation Fix
We also fixed a subtle bug where dynamically inserted elements (like form validation error messages) could cause ID collisions. The new parse_html_continue() function maintains ID counter continuity across parsing operations, ensuring that every element gets a unique identifier.
Upgrading to 0.1.6
Upgrading is simple:
pip install --upgrade djust
All optimizations are applied automatically. No code changes required. Your existing templates will render faster, and you can opt into lazy hydration for additional memory savings.
What's Next
We're continuing to push the performance envelope. Upcoming releases will include component-level template caching, parallel batch rendering for Rust components, and automatic query optimization based on template analysis.
Have feedback or questions? Join us on GitHub or check out our documentation for more details on these optimizations.
Related Posts
Full Django Template Compatibility: URL Tags, Comparison Operators, and Auto-Serialization
djust v0.1.6 brings major template system improvements including {% url %} tag support, {% include %} fixes, comparison operators in {% if %} conditions, and automatic Django type serialization.
Security-First Development: How djust Protects Your Application by Default
djust now includes built-in security utilities, automated vulnerability scanning, and pre-commit hooks to help you build secure applications from day one. Here's what's new in PR #40.
Introducing djust: Phoenix LiveView for Django
We are excited to announce djust, a framework that brings Phoenix LiveView-style reactive server-side rendering to Django. Build real-time, interactive web applications with Python - no JavaScript required.