When making visits to the same page you are already on, it's not always necessary to re-fetch all of the page's data from the server. In fact, selecting only a subset of the data can be a helpful performance optimization if it's acceptable that some page data becomes stale. Inertia makes this possible via its "partial reload" feature.
As an example, consider a "user index" page that includes a list of users, as well as an option to filter the users by their company. On the first request to the page, both the users
and companies
props are passed to the page component. However, on subsequent visits to the same page (maybe to filter the users), you can request only the users
data from the server without requesting the companies
data. Inertia will then automatically merge the partial data returned from the server with the data it already has in memory client-side.
To perform a partial reload, use the only
visit option to specify which data the server should return. This option should be an array of keys which correspond to the keys of the props.
import { router } from '@inertiajs/vue3'
router.visit(url, {
only: ['users'],
})
In addition to the only
visit option you can also use the except
option to specify which data the server should exclude. This option should also be an array of keys which correspond to the keys of the props.
import { router } from '@inertiajs/vue3'
router.visit(url, {
except: ['users'],
})
Since partial reloads can only be made to the same page component the user is already on, it almost always makes sense to just use the router.reload()
method, which automatically uses the current URL.
import { router } from '@inertiajs/vue3'
router.reload({ only: ['users'] })
It's also possible to perform partial reloads with Inertia links using the only
property.
import { Link } from '@inertiajs/vue3'
<Link href="/users?active=true" :only="['users']">Show active</Link>
For partial reloads to be most effective, be sure to also use lazy data evaluation when returning props from your server-side routes or controllers. This can be accomplished by wrapping all optional page data in a closure.
return Inertia::render('Users/Index', [
'users' => fn () => User::all(),
'companies' => fn () => Company::all(),
]);
When Inertia performs a request, it will determine which data is required and only then will it evaluate the closure. This can significantly increase the performance of pages that contain a lot of optional data.
Additionally, Inertia provides an Inertia::lazy()
method to specify that a prop should never be included unless explicitly requested using the only
option:
return Inertia::render('Users/Index', [
'users' => Inertia::lazy(fn () => User::all()),
]);
On the inverse, you can use the Inertia::always()
method to specify that a prop should always be included, even if it has not been explicitly required in a partial reload.
return Inertia::render('Users/Index', [
'users' => Inertia::always(User::all()),
]);
Here's a summary of each approach:
return Inertia::render('Users/Index', [
// ALWAYS included on standard visits
// OPTIONALLY included on partial reloads
// ALWAYS evaluated
'users' => User::all(),
// ALWAYS included on standard visits
// OPTIONALLY included on partial reloads
// ONLY evaluated when needed
'users' => fn () => User::all(),
// NEVER included on standard visits
// OPTIONALLY included on partial reloads
// ONLY evaluated when needed
'users' => Inertia::lazy(fn () => User::all()),
// ALWAYS included on standard visits
// ALWAYS included on partial reloads
// ALWAYS evaluated
'users' => Inertia::always(User::all()),
]);