How does Inertia 3 split page components into separate chunks, and when would you set pages.lazy to false instead?
answer
- lazy: true is the default
- import.meta.glob without eager
- one chunk per page, fetched on first visit
- eager: true builds one bundle
- a chunk is cached after first use
basics
~20 sBy default Inertia 3 lazy-loads page components, so Vite builds one chunk per page that downloads on its first visit; setting pages.lazy to false, or import.meta.glob with eager: true, bundles every page up front, trading a bigger first download for no per-page fetches.
solid answer
~50 sThe `@inertiajs/vite` plugin turns `pages` into a resolver over `import.meta.glob`, and `pages.lazy` defaults to `true`, so each page component becomes its own chunk that the browser fetches the first time a visit resolves that component. The first load stays small, which matters for a music app with dozens of screens, but the first visit to a page waits on the page JSON and a chunk download. `pages: { lazy: false }` (or `import.meta.glob(..., { eager: true })` in a hand-written `resolve`) puts every page in the main bundle: navigation never waits on a chunk, but every visitor downloads every page, including admin screens. Lazy loading suits large apps and pages few users open; eager suits small apps or kiosk-like screens. Link prefetching can take the page data off the critical path, but a lazy page's chunk still downloads when that page is first resolved.
code
jsx · 9 linesimport { createInertiaApp } from '@inertiajs/react'
createInertiaApp({
pages: {
path: './pages',
extension: '.jsx',
lazy: false, // bundle every page into the entry chunk
},
})go deeper
Know that Inertia loads page components lazily by default, so each page's code downloads when it is first needed.
Explain how the resolver and import.meta.glob produce chunks, the lazy option's default, and the eager alternative.
Choose lazy or eager per app from real usage, keep heavy libraries in the pages that need them, and measure first-visit cost on cold caches, not only warm ones.
Set performance budgets for the entry bundle and page chunks, and decide how splitting interacts with deploy cadence and caching.
## Where code splitting happens An **Inertia** client resolves each page component by name, for example `Albums/Show`, whenever a visit returns a page object. How that name maps to code decides how the JavaScript is split: - **lazy**: the resolver calls a dynamic import, so Vite emits one chunk per page and the browser downloads it on demand; - **eager**: every page is imported statically into the entry bundle. ## The Inertia 3 default With the `@inertiajs/vite` plugin, the `pages` option generates the resolver for you. Its object form accepts `path`, `extension`, `transform` and **`lazy`**, and `lazy` defaults to **`true`**. Without the plugin, the same choice is made in a hand-written `resolve`: | Style | Code | Result | |---|---|---| | lazy, plugin | `pages: './pages'` | one chunk per page | | eager, plugin | `pages: { path: './pages', lazy: false }` | all pages in the main bundle | | lazy, manual | `import.meta.glob('./pages/**/*.jsx')` and call the loader | one chunk per page | | eager, manual | `import.meta.glob('./pages/**/*.jsx', { eager: true })` | all pages in the main bundle | ## What each choice costs **Lazy loading** 1. The first load downloads only the entry, shared code and the first page's chunk. 2. The first visit to a new page needs two things: the page JSON from Laravel and the page's chunk. These can overlap only if the chunk was already requested. 3. Rarely used pages, such as admin screens or settings, never reach users who do not open them. **Eager loading** 1. Every visitor downloads every page in the first bundle. 2. Navigation never waits for a chunk. 3. The larger bundle slows the first load on slow connections and devices. ## Making lazy loading feel instant - Link **prefetching** fetches the target's page data ahead of the click, removing the server round trip from the wait; the page's chunk is still requested when its component is first resolved. - After the first visit, the chunk is in the browser cache, so later visits to that page only wait for JSON. - Keeping heavy libraries (a waveform renderer, a chart library) inside the pages that need them keeps them out of the main bundle. - Shared components used on most pages end up in shared chunks, not duplicated per page. ## A worked choice A music app has 40 pages: library, albums, artists, playlists, search, settings and an admin area. Most users open five of them. Lazy loading keeps the first load small, and the admin area never reaches listeners. An internal back-office tool with six pages used all day by the same staff might choose `lazy: false`, since after one download every navigation is immediate. ## Relation to other features - Persistent layouts are not split per page: a layout imported by most pages lands in a shared chunk and stays mounted anyway. - After a deploy, old chunk names disappear; Inertia's asset versioning forces a full reload so a stale tab does not request missing chunks. ## Common mistakes - switching to eager loading to fix one slow page, which slows the first load for everyone; - importing every page from a barrel file in the entry, which defeats splitting silently; - measuring navigation speed only on warm caches, where lazy chunks are already downloaded.
- Why can the first visit to a lazily loaded page feel slower than later visits?The first time, the client needs both the page JSON and the page's chunk; later visits reuse the cached chunk and only fetch JSON. Prefetching the link removes the JSON round trip from the wait, but the chunk still loads when the component is first resolved.
- What happens to lazily loaded chunks in an open tab after a deploy?The new build's chunks have new hashed names and the old ones may be gone. Inertia's asset version check turns the next visit into a full page load, so the tab loads the new entry and chunk names instead of requesting missing files.
saying these in an interview costs you the question
- Inertia 3 bundles all pages eagerly unless told otherwise
- Lazy loading splits the Laravel controllers as well
- Eager loading makes the first page load faster
- pages.lazy works without the @inertiajs/vite plugin
- Each lazy page chunk re-downloads on every visit