Building modern web applications requires balancing initial page performance with rich feature sets. Heavy dashboards and large datasets often choke initial page loads, degrading user experience before the first paint even completes. Inertia 3.x introduces powerful primitives that solve this challenge cleanly. By combining deferred props, lazy loading patterns, and rescue slots with Vue 3 and Server-Side Rendering (SSR), developers can ship lightning-fast interfaces without sacrificing complexity.
When building applications using a robust php web framework like Laravel, managing data transport between backend controllers and frontend components is central to day-to-day work. Leveraging modern php developer tools allows teams to focus entirely on application logic rather than boilerplate plumbing. Let us examine how Inertia 3.x handles data deferral, lazy execution, and error resilience.
Server-Side Mechanics: defer() vs lazy()
On the server, Inertia v3 provides distinct tools for handling slow or heavy data properties. Choosing between them depends entirely on your loading strategy.

Inertia::defer() ensures that heavy props do not block the initial HTTP response. After the primary page paint renders, the client automatically executes a follow-up partial reload to fetch the deferred data. This approach suits heavy dashboards and large collections that are not required for immediate rendering.
Inertia::lazy(), alternatively, wraps data in a closure that only executes when the client explicitly requests it via a partial reload. These properties remain untouched until triggered by specific user actions or visibility components.
Categorized Operations
- Added: Native server-side support for deferred and lazy closures.
- Changed: Non-blocking initial HTTP responses for heavy data payloads.
- Fixed: Elimination of bloated initial controller responses across complex routes.
For developers looking to build rest api with php or streamline monolithic Inertia endpoints, these primitives eliminate the need for manual API routing and separate asynchronous fetch calls.
Client-Side Rendering: The <Deferred> Component
In Vue 3, handling deferred data relies on the <Deferred> component provided by @inertiajs/vue3. This component manages the transition between loading states and final data rendering seamlessly.

<template>
<Deferred data="userData">
<template #fallback>
<UsersSkeleton />
</template>
<UsersList
:users="userData.users"
:total-users="userData.userCount"
/>
</Deferred>
</template>
<script setup>
import { Deferred } from '@inertiajs/vue3'
import UsersSkeleton '@/Components/UsersSkeleton.vue'
const props = defineProps({
userData: Object,
})
</script>
The data prop matches the name of the deferred property sent from your Laravel controller. While the background fetch resolves, the #fallback slot displays custom skeleton loaders or spinners. Once the payload arrives, Vue replaces the fallback with the primary component tree.
Visibility-Based Loading with <WhenVisible>
Lazy props require a trigger to initiate execution. Inertia provides the <WhenVisible> component, utilizing the Intersection Observer API to fetch data only when an element enters the browser viewport.

<template>
<WhenVisible data="topics">
<template #fallback>
<div class="animate-pulse">Loading topics...</div>
</template>
<TopicsList :topics="topics" />
</WhenVisible>
</template>
This pattern prevents wasted network requests on content hidden below the fold. You can configure buffer zones to trigger loading slightly before an element scrolls into view, ensuring a fluid experience for the user. Explore the complete ecosystem documentation at Laravel.
Error Resilience: Rescue Slots
Network failures and database exceptions happen. When a deferred property encounters an error during background loading, unhandled exceptions can break user workflows. Inertia 3.x introduces rescue functionality to handle these edge cases gracefully.

By configuring deferred properties with rescue support on the server, developers can utilize the #rescue slot on the client component.
<template>
<Deferred data="reports">
<template #fallback>
<ReportsSkeleton />
</template>
<template #rescue="{ reloading }">
<div class="text-red-600">
Failed to load reports.
<button @click="retry" :disabled="reloading">
Try again
</button>
</div>
</template>
<ReportsTable :reports="reports" />
</Deferred>
</template>
<script setup>
import { Deferred, router } from '@inertiajs/vue3'
const props = defineProps({
reports: Array,
})
const retry = () => {
router.reload({ only: ['reports'] })
}
</script>
The rescue slot receives a reloading boolean state. This lets you disable retry buttons while a recovery request is in flight, maintaining interface stability and clear user feedback.
SSR Considerations and Best Practices
Server-Side Rendering in Inertia 3.x interacts predictably with deferred and lazy data. Because deferred props do not block the initial response, the server renders the initial HTML containing the #fallback content for any <Deferred> or <WhenVisible> block.
Once hydration completes on the client, Inertia initiates the follow-up requests to populate those sections. This architecture guarantees fast Time to First Byte (TTFB) while preserving full SEO crawlability for your primary layout markup.
Implementation Checklist
- Audit controller methods to identify heavy payloads suitable for
defer(). - Wrap dependent Vue components in
<Deferred>with matching fallback states. - Implement
#rescueslots for resilient error recovery on critical data streams. - Verify SSR production builds using Vite to confirm proper hydration behavior.
Conclusion
Inertia 3.x bridges the gap between monolith simplicity and modern reactive frontend performance. By adopting deferred data streams, visibility triggers, and robust error rescue slots, your applications remain fast and reliable under heavy load. We would love to hear how you implement these patterns in your own projects.