💎 CRYSTAL Developer’s Diary #3: A Comparative Study of Performance and Cybersecurity of Client-Server Interaction in the LARS and SAHAR Technology Stacks.
September 28
upd: October 11
Table of Contents:
1. Introduction
As part of the continuous improvement of the CRYSTAL social network architecture and the search for the optimal technology stack for version CRYSTAL v3.0, I conducted a study of two architectural solutions: LARS and SAHAR.
This analysis includes a comprehensive performance audit, network load profiling, and an assessment of the cybersecurity level of client-server interaction.
The purpose of the study is to justify the selection of the most efficient, fault-tolerant, and secure architecture for the CRYSTAL social network.
2. Prototype Description
To conduct objective testing, I developed two functionally and visually identical prototypes. Both applications perform CRUD operations (Create, Read, Update, and Delete text in the database) interactively without a full page reload:
- Leptos v0.8.2.
- Actix Web v4.15.0.
- Rust v1.98.0.
- ScyllaDB v2026.2.6 (driver: v1.8.0).
- ScyllaDB v2025.4.0 (driver: v1.8.0).
- Actix Web v4.15.0.
- HTMX v4.0.0.
- Askama v0.16.
- Rust v1.98.0.
Architectural Feature of the Prototypes
The prototypes were designed in strict compliance with the Progressive Enhancement strategy.
Emulation of severe client environment constraints was carried out via the Mozilla Firefox browser configuration
settings (navigating to about:config). Disabling JavaScript was performed by toggling
the javascript.enabled parameter to false.
Additionally, for the LARS stack, forced WASM blocking was tested by toggling the javascript.options.wasm parameter to false.
The test results confirmed that both architectures retain 100% functionality when client-side technologies are disabled. The SAHAR stack remains operational when JavaScript is disabled. The LARS stack remains operational both when JavaScript is disabled and when WASM is disabled. In all these cases, the systems fall back to using native HTML forms with a full (classic) page reload, which ensures the fault tolerance of the interface.
3. Local PC Specifications and Test Environment
The deployment of the database, server infrastructure, project compilation, and network traffic profiling were carried out on a local PC with the following specifications:
- OS: Debian 12
- Browser: Mozilla Firefox Developer Edition 157.0b3 (64-bit), no plugins
- Network environment: local loopback interface
127.0.0.1 - CPU: i5-12600K
- RAM: 80GB DDR4
- GPU: RTX 3050 8GB
- SSD: Kingston KC600 256GB
4. Prototype Profiling (Dev/Debug and Release)
Stage 1: Profiling in Development Mode (Dev/Debug)
At the first stage, the build and launch of the projects were carried out in debug mode using the cargo leptos watch (LARS) and cargo run (SAHAR)
commands.
LARS Metrics Analysis (Dev/Debug)
Network traffic monitoring revealed significant overhead costs of the SPA architecture.
The total network payload during the initial application initialization amounted to 7.75 MB across 6 HTTP requests.
For the initial initialization, the browser is forced to download an unoptimized binary WASM module
(.wasm) of 7.66 MB in size, containing the complete reactivity engine and debug
symbols.
Integrating this module with the DOM tree requires an additional JavaScript bridge of 58.28 kB. At the same time, the
base
HTML document is 19.76 kB, as it includes an array of serialized data necessary for the hydration process (state
restoration) on the client.
SAHAR Metrics Analysis (Dev/Debug)
The total network payload during the initial application initialization amounted to 91.11 kB across 4 HTTP requests.
The transition to a hypermedia architecture demonstrated a radical optimization of the data exchange protocol even at
the development stage. The starting size of the HTML document was 2.60 kB. Dynamic interface updating is provided by a
single static HTMX script (using the basic minified version htmx.min.js without
additional GZIP compression) of 79.76 kB. There is no need to download WASM or use a virtual DOM.
Stage 2: Profiling in Production Mode (Release)
At the second stage, basic Rust release compiler optimizations (LLVM opt-level 3: Function Inlining, Constant
Folding, Dead Code Elimination) were applied to both prototypes, launched via the cargo leptos serve --release (LARS) and cargo run --release (SAHAR) commands. The commands were run without any additional
settings in Cargo.toml.
LARS Metrics Analysis (Release)
Standard release build optimization demonstrated significant results.
The total network payload during the initial application initialization was 806.31 kB across 5 HTTP requests.
The size of the transmitted WASM module was reduced to 771.96 kB, the JavaScript bridge size decreased to 25.47 kB,
and the HTML document to 1.89 kB. However, the fundamental architectural problem of the "Thick Client" persists: upon
dynamic data updating (saving/reading text), LARS initiates two separate POST requests (save_content
and get_content), transmitting serialized data in JSON format. Despite the small
payload size (123 B each), the browser is forced to parse the transferred JSON, process it via the WASM engine,
compute the virtual DOM diff, and only then initiate the UI repaint.
SAHAR Metrics Analysis (Release)
The total network payload during the initial application initialization was 91.11 kB across 4 HTTP requests. On the client side, the architecture retained its maximum lightweight nature: the starting HTML is 2.60 kB. The main architectural advantage is revealed during client-server interaction (saving or modifying text): instead of exchanging JSON data, the server returns a ready-made HTML micro-fragment of only 1.77 kB. The browser natively integrates this fragment into the target DOM tree node without performing any additional computational operations.
5. Comparison of the Initial HTML Response Structure
Initial HTML Response Structure for LARS (Release)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!>
<link rel="modulepreload" href="/pkg/enter_text_lars.js" crossorigin="Lsr7NfkNhwfrD_wwUzAssQ">
<link rel="preload" href="/pkg/enter_text_lars.wasm" as="fetch" type="application/wasm"
crossorigin="Lsr7NfkNhwfrD_wwUzAssQ">
<script type="module" nonce="Lsr7NfkNhwfrD_wwUzAssQ">(function (root, pkg_path, output_name, wasm_output_name) {
import(`${root}/${pkg_path}/${output_name}.js`)
.then(mod => {
mod.default({ module_or_path: `${root}/${pkg_path}/${wasm_output_name}.wasm` }).then(() => {
mod.hydrate();
});
})
})
("", "pkg", "enter_text_lars", "enter_text_lars");</script><!--HEAD-->
<link id="leptos" rel="stylesheet" href="/pkg/enter_text_lars.css">
<title>Enter Text (LARS)</title>
</head>
<body>
<main>
<div class="container">
<h1 class="title">Enter Text (LARS)</h1>
<div class="card">
<p class="card-label">Text from ScyllaDB:</p>
<h2 class="db-text">Sample text</h2>
<hr class="separator">
<div class="controls">
<form action="/api/save_content18064880299772172936" method="post">
<div class="input-row"><input type="text" name="content" placeholder="Enter text..."
class="input-field"><button type="submit" class="btn btn-black">Update</button></div>
</form>
<form action="/api/delete_content18064880299772172936" method="post"><button type="submit"
class="btn btn-red">Delete</button></form>
</div>
</div>
</div>
</main>
</body>
</html>
<script
nonce="Lsr7NfkNhwfrD_wwUzAssQ">__RESOLVED_RESOURCES = []; __SERIALIZED_ERRORS = []; __PENDING_RESOURCES = [0,]; __RESOURCE_RESOLVERS = [];</script>
<script nonce="Lsr7NfkNhwfrD_wwUzAssQ">__RESOLVED_RESOURCES[0] = "\"Sample text\"";</script>
<script nonce="Lsr7NfkNhwfrD_wwUzAssQ">__INCOMPLETE_CHUNKS = [];</script>
The LARS architecture successfully implements Server-Side Rendering (SSR). The data: <h2>Sample text</h2> is already embedded in the DOM tree at the time the page
is served by the server. This guarantees excellent SEO performance, as search engine crawlers instantly index the
content without the need to execute JavaScript.
However, the analysis reveals a fundamental architectural conflict between the SPA hydration mechanics and modern
cybersecurity standards. In order to prevent the WASM client from making a redundant "idle" database request upon
initial page load, the Leptos framework is forced to serialize the initial database state (__RESOLVED_RESOURCES) and inject it directly into the HTML document as an inline script,
where the WASM module initialization script is also placed.
From a cybersecurity perspective, the presence of any inline scripts is the primary vulnerability for XSS (Cross-Site
Scripting) attacks. To protect the system, a strict CSP (Content Security Policy) is implemented, blocking the
execution of any inline code. And this is exactly where the LARS architecture faces an inevitable compromise: to allow
the execution of Leptos's own system scripts but block malicious scripts, the Actix Web server must spend CPU time
generating a unique cryptographic key —
nonce (e.g., nonce="Lsr7NfkNhwfrD_wwUzAssQ") on
every HTTP request. The server must dynamically inject this key into both the HTTP headers and every <script> tag in the DOM tree. This mechanism is vital for LARS, but it inevitably
increases the computational load on the server and complicates the content delivery pipeline.
At the same time, it is worth noting the high design standard of Leptos: out of the box, the framework encourages
adherence to the Progressive Enhancement strategy. It is enough to use the basic declarative component <ActionForm action=save_content_action>, and during SSR generation, Leptos will
automatically output the correct markup with native HTML action and method attributes. This ensures that if the WASM module fails to download due to a
network failure or blocking, saving the data will occur via a classic form submission with a page reload.
Initial HTML Response Structure for SAHAR (Release)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Enter Text (SAHAR)</title>
<!-- HTMX Configuration: disable inline indicator styles to comply with strict CSP -->
<meta name="htmx-config" content='{"includeIndicatorStyles": false}'>
<link rel="stylesheet" href="/static/style.css" />
<link rel="icon" type="image/x-icon" href="/static/favicon.ico" />
<!-- Include HTMX -->
<script src="/static/htmx.min.js?v=4.0.0"></script>
</head>
<body>
<div class="container">
<h1 class="title">Enter Text (SAHAR)</h1>
<div class="card" id="content-card">
<p class="card-label">Text from ScyllaDB:</p>
<div class="text-wrapper">
<!-- Askama automatically escapes Sample text, preventing XSS attacks -->
<h2 class="db-text">Sample text</h2>
</div>
<hr class="separator" />
<div class="controls">
<!-- Save/Update form (works with JS via HTMX and without JS) -->
<form action="/api/content" method="POST" hx-post="/api/content" hx-target="#content-card" hx-swap="innerHTML"
hx-indicator="#content-card">
<div class="input-row">
<!-- Added maxlength="1000" for client-side protection against huge data inputs -->
<input type="text" name="content" placeholder="Enter text..." class="input-field" autocomplete="off"
required maxlength="1000" />
<button type="submit" class="btn btn-black">
Update
</button>
</div>
</form>
<!-- Delete text form (works with JS via HTMX and without JS) -->
<form action="/api/content/delete" method="POST" hx-post="/api/content/delete" hx-target="#content-card"
hx-swap="innerHTML" hx-indicator="#content-card">
<button type="submit" class="btn btn-red">Delete</button>
</form>
</div>
</div>
</div>
</body>
</html>
The SAHAR architecture generates benchmark clean, semantic HTML code. Data from ScyllaDB is embedded into the markup on the server side (Askama), ensuring perfect SEO indexing and instant First Contentful Paint.
In the context of cybersecurity, the SAHAR architecture demonstrates maximum reliability. Since the markup is
completely devoid of inline scripts, embedded blocks of serialized JSON state, or module loaders, there is no need to
dynamically generate resource-intensive nonce hashes for the HTML document. All
interactivity is declared exclusively via the safe attributes of the static HTMX script (hx-post, hx-target).
The absence of client-side rendering allows for the implementation of uncompromising CSP settings, completely
eliminating the 'unsafe-inline' directive for both scripts (script-src 'self') and styles (style-src 'self').
To meet strict security standards, I overrode the default HTMX behavior by forbidding it from dynamically injecting
styles into the DOM tree (via the configuration <meta name="htmx-config" content='{"includeIndicatorStyles": false}'>) in the index.html file, and moved all visual logic into a secure external CSS file (style.css). Such architectural control preemptively narrows the attack surface to an
absolute minimum, making the system completely invulnerable to both XSS (Cross-Site Scripting) and CSS injections (UI
Redressing).
An additional and critically important cybersecurity layer of the SAHAR stack is the protection against Cross-Site
Request Forgery (CSRF). Unlike classic SPAs, which require complex CSRF token management, the combination of HTMX and
Actix Web allows the implementation of elegant and robust Anti-CSRF Middleware. At the level of each request, the
server strictly validates the Origin and Referer
HTTP headers. Since the HTMX script natively and correctly transmits these headers with every data mutation, the
backend instantly blocks any POST/DELETE requests initiated from third-party domains.
This completely eliminates the possibility of session hijacking and hidden command execution on behalf of an
authorized user of the social network.
Global Security Configuration
To ensure comprehensive architectural protection at the HTTP server level, a specialized protection layer (middleware) is integrated into the Actix Web configuration. This configuration block preemptively blocks a whole vector of vulnerabilities: from DoS attacks to Clickjacking and MIME-sniffing attempts:
.app_data(app_state.clone())
// Incoming data limit (Protection against DoS attacks via huge payloads)
.app_data(web::FormConfig::default().limit(4096))
// Strict security headers (Zero 'unsafe-inline' tolerance)
.wrap(
middleware::DefaultHeaders::new()
// Protection against Clickjacking
.add(("X-Frame-Options", "DENY"))
// Protection against MIME-sniffing
.add(("X-Content-Type-Options", "nosniff"))
.add((
"Content-Security-Policy",
// Disable inline scripts and styles. Allow own Origin ('self') only
"default-src 'self'; script-src 'self'; style-src 'self';",
))
.add((
"Strict-Transport-Security",
"max-age=31536000; includeSubDomains; preload",
))
.add(("Referrer-Policy", "strict-origin-when-cross-origin")),
)
Just as with LARS, the forms are designed based on the Progressive Enhancement principle. The
presence of standard
action and method attributes ensures that the basic
CRUD functionality will work flawlessly even in an environment with JavaScript completely disabled:
<!-- Save/Update form (works with JS via HTMX and without JS) -->
<form action="/api/content" method="POST" hx-post="/api/content" hx-target="#content-card" hx-swap="innerHTML"
hx-indicator="#content-card">
<div class="input-row">
<!-- Added maxlength="1000" for client-side protection against huge data inputs -->
<input type="text" name="content" placeholder="Enter text..." class="input-field" autocomplete="off"
required maxlength="1000" />
<button type="submit" class="btn btn-black">
{% if is_empty %}Add{% else %}Update{% endif %}
</button>
</div>
</form>
Comparative Table of the Initial HTML Response Structure
| Criterion | LARS (Leptos + WASM) | SAHAR (Askama + HTMX) |
|---|---|---|
| SEO Indexing | Excellent (SSR content in DOM) | Excellent (SSR content in DOM) |
| HTML Structure and Security (CSP) | Complicated: requires inline state scripts and 'nonce' key generation | Clean: no inline scripts, 'nonce' generation in DOM is not required |
| Client Hydration | Required (WASM download and initialization) | Not required (only HTML micro-fragments) |
6. Comparative Analysis of Network Exchange During Data Mutation
LARS Exchange Mechanics (2 POST requests)
The LARS architecture uses the classic isomorphic SPA model (Client-Side Hydration), which separates the process of mutating data and the process of updating the user interface into two independent RPC steps:
- Request 1, size: 123 B (
POST /api/save_content...): When the update text button is clicked, the WASM module intercepts the form event and calls the generated server function. The client sends serialized JSON to the server. The Actix Web handler writes the new data to ScyllaDB and returns a basic successful transaction confirmation (HTTP 200) to the client. - Request 2, size: 123 B (
POST /api/get_content...): Upon receiving confirmation of a successful write, the Leptos reactive system automatically marks the associated resource (Resource) on the client as "stale" (invalidates it). To display the up-to-date data in the interface, the WASM client is forced to initiate a second RPC request to the database. It requests the fresh state, receives the updated JSON in response, parses it on the client side, and recalculates the Virtual DOM for repainting.
Screenshot 5: Profiling LARS network exchange during data mutation: a two-stage RPC protocol (JSON write and repeated resource read)
SAHAR Exchange Mechanics (1 POST request)
The SAHAR architecture operates on the principles of a Hypermedia-Driven Application (HTMX + Askama + Actix Web), where data mutation and interface rendering are combined into a single atomic server transaction:
- Single request, size: 1.77 kB (
POST /api/content): The HTMX library intercepts the form submission and forms a single POST request, explicitly indicating via attributes that it expects an HTML response to replace a block (hx-post="/api/content",hx-target="#content-card",hx-swap="innerHTML"). - Atomic processing on the server: The
save_contentserver handler in Actix Web accepts the request and immediately saves the new text to the ScyllaDB database. Then it checks for the presence of thehx-requestheader. If the header is present, the server renders theContentTemplatestructure via the Askama template engine within the same HTTP connection and returns the ready-made HTML code. - UI update without client state: The browser receives the pre-rendered HTML fragment, and HTMX
instantly replaces the contents of the
#content-cardcontainer with it. Since there is no State and no virtual DOM on the client, the need for a second request for data synchronization is completely eliminated.
Screenshot 6: Profiling SAHAR network exchange during data mutation: a single Hypermedia request (atomic save and HTML return)
Technical Justification for the Difference in Network Requests
The fundamental difference between the two POST requests in LARS and one POST request in SAHAR is due to the difference in architectural approaches to State Management and the data transfer format between the client and server.
Results of the Comparative Analysis of Network Exchange During Data Mutation
The implementation of the SAHAR architecture allows for:
- 1. Reducing network overhead (Round-Trip Time) by 2 times.
- 2. Decreasing the load on the ScyllaDB database by eliminating idle read requests immediately after a write.
- 3. Completely freeing the client device from the computational load of JSON parsing and Virtual DOM diffing.
7. General Conclusions
Cybersecurity
The SAHAR stack minimizes potential attack vectors. The absence of client-side business logic at the JavaScript/WASM level preemptively eliminates an entire class of vulnerabilities. Strict isolation of computational processes on the server side guarantees total concealment of the source code from the end user. In the LARS architecture, part of the system logic is inevitably delegated to the client side, which reduces the overall level of security.
Speed and Performance
Thanks to the hypermedia architecture and the shift of state management to the server, the SAHAR stack provides instant interface loading. The client receives lightweight, pre-rendered HTML, which completely eliminates any time spent downloading, parsing, and hydrating massive WASM modules or JS state managers. This approach guarantees an immediate First Contentful Paint and minimal Time to Interactive, even under unstable mobile connection conditions.
SEO
Thanks to the isomorphic approach, both stacks provide initial Server-Side Rendering (SSR), giving search engine crawlers access to the page's content. However, the LARS architecture requires downloading and initializing a bulky WASM module for hydration. This significantly increases the Time to Interactive and Total Blocking Time metrics. The SAHAR stack, by delivering lightweight HTML without the need for complex hydration, ensures benchmark Core Web Vitals performance, giving it an undeniable advantage in search engine ranking.
DOM Structure Transparency and Maintainability
The SAHAR architecture generates a semantically clean HTML document. Declarative dynamic state management via HTMX attributes provides high DOM tree transparency on the client side. Unlike the LARS architecture, where the base markup is inevitably overloaded with hydration artifacts and initialization scripts, the SAHAR approach radically simplifies the debugging process and reduces the overhead for future maintenance of the codebase.
Energy Efficiency
In the SAHAR architecture, the primary computational load is shifted to the server hardware. The end user's device mainly performs native rendering of the ready-made HTML code and lightweight replacement of DOM tree nodes by the HTMX script, which significantly reduces RAM consumption and battery drain on mobile devices.
8. Summary Table of Comparative Characteristics (LARS vs SAHAR)
| Criterion | LARS | SAHAR |
|---|---|---|
| Architectural Approach | Isomorphic SPA (SSR + Client-Side Hydration) | Hypermedia-Driven (SSR + HTMX) |
| Static Assets Size (Dev/Debug (cargo)) | HTML: 19.76 kB, WASM: 7.66 MB, JS: 58.28 kB | HTML: 2.60 kB, HTMX: 79.76 kB (htmx.min.js without compression) |
| Static Assets Size (Release (cargo)) | HTML: 1.89 kB, WASM: 771.96 kB, JS: 25.47 kB | HTML: 2.60 kB, HTMX: 79.76 kB |
| Exchange Format (CRUD) | JSON (2 separate requests, parsing required) | Generated HTML fragment (1 request, 1.77 kB) |
| Computational Load | High: WASM processing, Virtual DOM diffing | Minimal: native HTML rendering by the browser |
| Attack Surface | Expanded: part of the logic is executed on the client | Minimal: 100% of the logic is isolated on the server |
| JS Dependency | Full fault tolerance (Progressive Enhancement): functionality preserved via native forms | Full fault tolerance (Progressive Enhancement): functionality preserved via native forms |
9. Conclusion
The results of the profiling confirm that the SAHAR architecture outperforms LARS across all key metrics: cybersecurity, loading speed, SEO optimization, and end-device energy efficiency.
The rejection of the Single Page Application architecture in favor of hypermedia server micro-responses fully aligns with modern engineering standards for designing secure, high-load systems.
Share












Comment on