Choose your dist folder. See what loads at start, what loads later, why each file is in the first load, and which chunks break your budget.
To check how big your Vite bundle is at first load, choose the dist folder from vite build, or paste .vite/manifest.json, and this page lists every file the entry loads at start with its raw and gzip size, then compares the total with a budget you set. It follows the rule in the Vite backend-integration guide: the entry's CSS, then the CSS of every chunk the entry imports statically, the entry file, and each statically imported chunk, recursively. Dynamic imports are not part of it. Worked example with the sample that opens on the page: index at 62,000 bytes gzip, vendor-react at 45,500, vendor-ui at 96,000 and the stylesheet at 6,200 add up to 209,700 bytes, which is 204.8 KB. Against a 200 KB budget that is 4.8 KB over. The Why it is here column shows the shortest static import path, such as index > vendor-ui, so you can see which import to cut or make dynamic.
A lazy chunk is one the manifest lists under dynamicImports, usually a route or a heavy component loaded with import(). The table gives two numbers for each. Own is the chunk's file plus its CSS. Cost when loaded also counts the static dependencies that are not already in the initial load, which is what a visitor actually downloads when the route opens. In the sample, Reports is 38,000 bytes gzip plus 2,400 of CSS, so 39.5 KB alone. It also imports a charts chunk of 118,000 bytes that the first screen does not have, so opening Reports costs 154.7 KB, which is 54.7 KB over a 100 KB budget. Settings reuses vendor-ui from the initial load, so it costs only its own 9.8 KB. The lazy budget is checked against the cost when loaded, not the own size, because a small route that pulls in a large library is still a large download.
Sizes use 1 KB = 1024 bytes. Choosing a folder gives exact raw sizes and gzip sizes from your browser's gzip, which does not offer brotli, so brotli is shown only when you paste the bundle.json that the terminal command on the page writes. That command also gzips at level 9, so its numbers can differ a little from the browser's and from your build log. Budgets are numbers you choose. The defaults, 200 KB for the initial load and 100 KB per lazy chunk, are starting points, not a standard, and you can judge raw or gzip. Assets such as images and fonts are named by the manifest but are not part of the initial total, because browsers fetch them when something uses them. A file the manifest names but the folder lacks is shown with an unknown size and left out of the totals, and a budget that depends on an unknown size is marked unknown, not passed. The browser gzips files up to 64 MiB each and measures at most 1,500 files; larger files keep only a raw size. A CSS-only entry counts as an entry.
Under Compare with another build, choose an older dist folder or paste its manifest. Chunks are matched by source path, then by name, then by file name with the 8-character hash removed, so assets/index-BqVx3k2P.js and assets/index-Ak92LmPq.js count as the same chunk, and the table lists only chunks that changed, largest change first. In the sample the entry grew from 47,500 to 62,000 bytes gzip, 14.2 KB more. If a folder has no manifest, the page falls back to the script, modulepreload and stylesheet tags in index.html. That gives the entry and its preloads for certain, but it can only guess that every other .js file is lazy, and it says so. The page does not look inside a chunk, so it cannot say which module is large, and it does not read source maps. An agent can run the terminal command and open this page with the JSON after #input=, as long as it fits the 100,000 characters a link can carry.
Set build.manifest to true in vite.config, run vite build, then choose the dist folder on this page. It reads .vite/manifest.json (Vite 5 and later) or manifest.json (older) and shows the initial load as one total, such as 204.8 KB gzip, with every file and the path that pulls it in.
The entry file, its CSS, and every chunk the entry imports statically, with their CSS, following imports recursively. Chunks reached only through import() are lazy and are listed separately. Images and fonts are not counted, since browsers fetch them when they are used.
Open the Why it is here column. A large vendor chunk reached as index > vendor-ui means an import in your entry pulls it in. Turn that import into a dynamic import(), or split the library into its own chunk with the manualChunks output option, then rebuild and compare with the older build to see the change in KB.
The page falls back to the script, modulepreload and stylesheet tags in index.html. It then knows the entry, its preloaded chunks and its CSS, but it can only guess that other .js files are lazy and cannot name who loads them. Turn on build.manifest for the full graph.
The page uses 1 KB = 1024 bytes and your browser's gzip, while a build tool may use another KB size or gzip level. The terminal command on the page gzips at level 9 and adds brotli. Compare numbers from the same tool across builds, not across tools.
No. The files are read in your browser and not uploaded, even though the browser's folder prompt may mention uploading. Only the files the manifest names are measured, and the page counts visits with Google Analytics, using rough size groups such as 1 to 10 MB, never a file name.