Partial Reloads¶
Optimize performance by reloading only specific props.
See also
Official Inertia.js docs: Partial Reloads
What Are Partial Reloads?¶
Partial reloads let you request only specific props instead of the entire page data. This reduces payload size and server processing.
Lazy Props¶
Use lazy() to mark props that should only load during partial reloads:
from typing import Any
from litestar import get
from litestar_vite.inertia import lazy
@get("/dashboard", component="Dashboard")
async def dashboard() -> dict[str, Any]:
return {
"stats": get_stats(), # Always included
"notifications": lazy("notifications", get_notifications), # Partial only
"activity": lazy("activity", get_activity_feed), # Partial only
}
Lazy props are excluded from the initial page load and only sent when explicitly requested via partial reload.
Static vs Callable Lazy Props¶
Static value - computed eagerly, sent lazily:
# Value computed now, but only sent during partial reload
lazy("count", len(expensive_query()))
Callable - computed and sent lazily:
# Function only called during partial reload
lazy("count", lambda: len(expensive_query()))
lazy("data", expensive_async_function) # Async works too
Warning
Avoid the “False Lazy” pitfall:
# WRONG - function called immediately!
lazy("data", get_expensive_data())
# CORRECT - function reference passed
lazy("data", get_expensive_data)
Once Props¶
Use once() to cache props client-side after the first response:
from typing import Any
from litestar import get
from litestar_vite.inertia import once
@get("/settings", component="Settings")
async def settings() -> dict[str, Any]:
return {
"preferences": once("preferences", get_preferences),
"feature_flags": once("feature_flags", get_feature_flags),
}
Once props are included in initial loads, but the client caches their values and reuses them on subsequent visits.
Optional Props (WhenVisible)¶
Optional props are only included when explicitly requested:
from typing import Any
from litestar import get
from litestar_vite.inertia import optional
@get("/posts/{post_id}", component="Posts/Show")
async def show_post(post_id: int) -> dict[str, Any]:
return {
"post": await Post.get(post_id),
"comments": optional("comments", lambda: Comment.for_post(post_id)),
}
These work well with the WhenVisible component to load data as it enters
the viewport.
Always Props¶
Use always() for data that must be included in every response, even when
partial reloads filter props:
from typing import Any
from litestar import get
from litestar.request import Request
from litestar_vite.inertia import always, lazy
@get("/dashboard", component="Dashboard")
async def dashboard(request: Request) -> dict[str, Any]:
return {
"auth": always("auth", {"user": request.user}),
"stats": lazy("stats", get_stats),
}
Prop Type Comparison¶
Type |
Initial Load |
Partial Reloads |
Typical Use |
|---|---|---|---|
|
Excluded |
Included when requested |
Heavy data on demand |
|
Excluded |
Only when explicitly requested |
WhenVisible / viewport loading |
|
Included, cached |
Reused unless requested |
Rarely changing data |
|
Included |
Included even when filtered |
Critical auth/context |
Frontend Partial Reloads¶
Request specific props from the client:
import { router } from "@inertiajs/react";
// Reload only specific props
router.reload({ only: ["notifications"] });
// Exclude specific props
router.reload({ except: ["stats"] });
import { router } from "@inertiajs/vue3";
router.reload({ only: ["notifications"] });
router.reload({ except: ["stats"] });
Prop Filtering Helpers¶
Use only() and except_() for server-side filtering:
from litestar_vite.inertia import only, except_
# Include only specific props
filter_users = only("users", "pagination")
# Exclude specific props
filter_no_debug = except_("debug_info", "internal_stats")
# Check if a key should be included
if filter_users.should_include("users"): # True
pass
if filter_users.should_include("settings"): # False
pass
Protocol Headers¶
The v2 protocol uses these headers for partial reloads:
Header |
Description |
|---|---|
|
Comma-separated list of props to include (e.g., |
|
Comma-separated list of props to exclude (takes precedence over Partial-Data) |
|
Comma-separated list of props to reset/remove from shared state |
When X-Inertia-Partial-Except is present, it takes precedence over
X-Inertia-Partial-Data. This matches the v2 protocol behavior where
exclusion is stronger than inclusion.
Reset Props¶
The X-Inertia-Reset header removes specified props from the shared state:
// Client-side: reset specific props during partial reload
router.reload({
only: ["users"],
reset: ["flash", "errors"] // Clear flash and errors
})
On the backend, reset props are removed from shared_props before
building the page response. This is useful for clearing one-time data
like flash messages or validation errors.
Example Use Case¶
Dashboard with heavy charts data:
from typing import Any
from litestar import get
from litestar_vite.inertia import lazy
@get("/dashboard", component="Dashboard")
async def dashboard() -> dict[str, Any]:
return {
"user": get_current_user(), # Always needed
"summary": get_summary_stats(), # Always needed
"charts": lazy("charts", get_chart_data), # Load on demand
"activity": lazy("activity", get_activity), # Load on demand
}
Frontend:
// Initial load: only user and summary
// Click "Load Charts" button:
router.reload({ only: ["charts"] });
See Also¶
Deferred Props - Auto-loaded deferred props
Responses - InertiaResponse options
Once Props - Client-cached props
Load When Visible - Optional props with WhenVisible