Inertia.js v2 was the release that closed most of the perceived gap between an Inertia app and a classic SPA built on client-side data fetching. Deferred props, prefetching, polling and infinite scroll — features that used to require hand-written state machines — are now first-class, server-driven primitives. Here is how each one works in practice and what it changes for the user.
If you are new to the architecture itself, start with Inertia.js with Laravel and React — SPA without a separate API.
Deferred props — fast first paint, heavy data later
A dashboard often mixes light data (user, counters, permissions) with heavy queries (charts, aggregates, activity feeds). Deferred props split the response in two: the page renders immediately with the light data, and heavy props arrive in a second request.
// Laravel — the heavy prop is deferred
return Inertia::render('Dashboard', [
'stats' => fn () => StatsService::summary($user),
'revenueChart' => Inertia::defer(fn () => RevenueService::monthly($user)),
]);
On the React side the component shows a skeleton until the data lands
import { Deferred } from '@inertiajs/react';
export default function Dashboard({ stats, revenueChart }) {
return (
<div>
<StatCards data={stats} />
<Deferred data="revenueChart" fallback={<ChartSkeleton />}>
<RevenueChart data={revenueChart} />
</Deferred>
</div>
);
}
Use it for anything that can arrive half a second late without breaking comprehension. Combined with SSR it is especially effective: the server sends full HTML for the light data, and the heavy widgets hydrate as they arrive — see Inertia.js SSR with Laravel.
Prefetching — instant navigation
<Link href="/orders" prefetch>Orders</Link>
On hover (or mount, if you prefer) Inertia fetches the target page in the background. By the time the user clicks, the response sits in the cache and the page swaps instantly. In our apps we prefetch the two or three destinations every user visits next — detail pages from lists, the primary dashboard, the most-used report.
Tip: Prefetch selectively. Prefetching every link turns idle time into server load; prefetch the likely next step, not the whole navigation menu.
Polling — live data without WebSockets
import { usePoll } from '@inertiajs/react';
// refresh only the 'stats' prop every 5 seconds
usePoll(5000, { only: ['stats'] });
Polling with only re-fetches just the props you name, not the whole page — the round-trip stays small. For job queues, delivery statuses and KPI counters this replaces a WebSocket stack entirely. Reach for real-time infrastructure only when updates must be sub-second or collaborative.
Infinite scroll and merging
import { router } from '@inertiajs/react';
// append the next page instead of replacing the prop
router.reload({ only: ['orders'], data: { page: nextPage } });
With prop merging, list pages keep what is already rendered and append new pages — the classic infinite scroll, driven by server-side pagination and Laravel's query builder rather than a client-side data layer.
Optimistic updates and instant visits
v2 also lets you update the UI before the server confirms. Combined with router.optimistic, like buttons, task checkboxes and kanban moves feel instant while Laravel processes the request in the background — and roll back automatically if the request fails.
What it means for your app
- The common thread: each feature moves a piece of perceived performance out of the client's JavaScript and into the server-driven page model. You get SPA-grade responsiveness without an API layer, without client-side caches to invalidate, and with Laravel as the single source of truth. Our production stack — used in OneCRMApp and client portals — runs deferred props, selective prefetching and polling as defaults.
Want this performance profile in your product?
See Laravel development services.
FAQ
Deferred props vs lazy loading?
Deferred props split one page response into two phases so the layout paints immediately; lazy loading usually means below-the-fold assets. Different tools for different bottlenecks.
Does prefetching hit the server?
Yes — it is the same request a click would trigger, sent on hover and cached. Server load shifts earlier rather than growing.
Polling instead of WebSockets?
For dashboards, counters and job statuses — yes, polling every few seconds is simpler and sufficient. For chat and presence, use WebSockets.
👉 Want an Inertia.js app that feels instant? Check our Laravel development services or hire a Laravel developer.
📖 Read more: Inertia.js with Laravel and React, Inertia.js SSR with Laravel and forms and validation with useForm.