docs(perf): optimizePackageImports is inert here - Turbopack makes it a no-op
Seven Mantine entry points were missing from optimizePackageImports while core/hooks/icons-react were listed. Added all seven, rebuilt, and the client bundle came out byte-for-byte identical: 482 files, 18050.7 KiB, same largest chunk, same chunk hashes. Identical output down to the hashes normally means a cached build, and turbopackFileSystemCacheForBuild is enabled here, so it got checked rather than written up as a null result. The Next.js docs are explicit: "This is not needed when using Turbopack. Turbopack automatically analyzes and optimizes imports without requiring this configuration." The build banner confirms Turbopack. So the change is reverted and the existing three-entry list documented as dead config, kept only as a webpack fallback. This also retires the sub-question of whether @homarr/ui - the largest barrel at 111 importers - could be optimised this way: it cannot, and it does not need to be. Two notes for anyone revisiting: Next 16 with Turbopack prints no size columns in its route table and emits no app-build-manifest.json, so per-route first-load JS is unavailable from build output; these numbers are total bytes under .next/static/chunks.
This commit is contained in:
4 files changed
+59
-13
No files matched your search
@@ -84,6 +84,15 @@ const nextConfig: NextConfig = {
|
||||
"@ioredis/commands",
|
||||
],
|
||||
experimental: {
|
||||
/**
|
||||
* Dead config under Turbopack, which this app builds with: "Turbopack automatically analyzes and
|
||||
* optimizes imports without requiring this configuration."
|
||||
*
|
||||
* Measured rather than assumed - adding the seven Mantine entry points that are missing here
|
||||
* (charts, dates, dropzone, form, notifications, spotlight, tiptap) produced a client bundle that
|
||||
* was byte-for-byte identical, 482 files and 18050.7 KiB in both arms, down to the chunk hashes.
|
||||
* Kept only as a fallback for a webpack build; do not add to it expecting an effect.
|
||||
*/
|
||||
optimizePackageImports: ["@mantine/core", "@mantine/hooks", "@tabler/icons-react"],
|
||||
turbopackFileSystemCacheForBuild: true,
|
||||
useTypeScriptCli: true,
|
||||
|
||||
@@ -81,7 +81,6 @@ Start from `analyze-require-graph.mjs`, which found the shared subtree, and
|
||||
| Lazy `mysql2` / `pg` | 21.4 MiB | Three implementations, all broken; see REJECTED.md. Structurally blocked because `createDb` must stay synchronous |
|
||||
| `beszelSystemStats` at 1,156 nodes | unknown | Second-heaviest widget, but its cost is chart SVG (`<g>×317`), so reducing it changes what is drawn |
|
||||
| `documents` reads 18–32 | unknown | Never investigated; each document carries overhead |
|
||||
| Add 7 Mantine entry points to `optimizePackageImports` | unknown | One line: `dates`, `dropzone`, `charts`, `spotlight`, `form`, `notifications`, `tiptap` are not listed, while `core`/`hooks`/`icons-react` are. Needs two production builds and a first-load-JS diff to know whether it does anything. `@homarr/ui` is **not** eligible despite 111 importers — Next's barrel optimiser only rewrites pure re-export files, and `packages/ui/src/index.ts` also defines a runtime value |
|
||||
|
||||
## 4. For the clean PR
|
||||
|
||||
|
||||
@@ -3,6 +3,35 @@
|
||||
Each of these was implemented or configured, built, and measured. They are recorded with their
|
||||
numbers so nobody repeats them, and because several looked like wins until the measurement came in.
|
||||
|
||||
## `optimizePackageImports` — inert, because this app builds with Turbopack
|
||||
|
||||
Seven Mantine entry points were absent from `experimental.optimizePackageImports` while
|
||||
`@mantine/core`, `@mantine/hooks` and `@tabler/icons-react` were listed: `charts`, `dates`,
|
||||
`dropzone`, `form`, `notifications`, `spotlight`, `tiptap`. Adding all seven and rebuilding:
|
||||
|
||||
| | baseline | all seven added |
|
||||
| --- | --- | --- |
|
||||
| client chunk files | 482 | 482 |
|
||||
| client chunk bytes | 18050.7 KiB | 18050.7 KiB |
|
||||
| largest chunk | 2341.5 KiB | 2341.5 KiB |
|
||||
|
||||
**Byte-for-byte identical, down to the chunk hashes.** That pattern normally means a cached build — and
|
||||
`turbopackFileSystemCacheForBuild` is enabled here — so it was checked rather than written up as a null
|
||||
result. The Next.js documentation is explicit: *"This is not needed when using Turbopack. Turbopack
|
||||
automatically analyzes and optimizes imports without requiring this configuration."* The build banner
|
||||
reads `Next.js 16.3.0-preview.9 (Turbopack)`.
|
||||
|
||||
So the existing three-entry list is also dead config. It is left in place as a fallback should the app
|
||||
ever build with webpack again, with a comment saying not to expect anything from it.
|
||||
|
||||
This retires the entire "barrel imports / bundle optimization" line of enquiry for this repo, including
|
||||
the sub-question of whether `@homarr/ui` — the biggest barrel at 111 importers — could be optimised.
|
||||
It cannot be by that mechanism, and does not need to be.
|
||||
|
||||
Two measurement notes for anyone revisiting this: Next 16 with Turbopack prints **no size columns** in
|
||||
its route table and emits no `app-build-manifest.json`, so per-route first-load JS is not available
|
||||
from the build output. Total bytes under `.next/static/chunks` is what these numbers are.
|
||||
|
||||
## `--jitless` — looked like the biggest win of the entire investigation, and was fake
|
||||
|
||||
V8's `--jitless` removes the optimising compiler and all generated machine code. Its effect on code
|
||||
|
||||
+21
-12
@@ -167,21 +167,30 @@ would be user-visible — `custom-api`'s user JSX, the edit modal's forms — th
|
||||
The cost is real and worth stating: switching tabs in `health-monitoring` or `media-missing` now
|
||||
remounts the panel. react-query still has the data cached, so it repaints rather than reloads.
|
||||
|
||||
### Bundle: partially satisfied
|
||||
### Bundle: the rule does not apply here at all
|
||||
|
||||
`optimizePackageImports` already covers the three that matter by volume — `@mantine/core` (727
|
||||
imports), `@mantine/hooks` (69), `@tabler/icons-react`. Seven smaller Mantine entry points are not
|
||||
listed: `dates` (13 files), `dropzone` (12), `charts` (10), `spotlight` (7), `form` (4),
|
||||
`notifications` (3), `tiptap` (1).
|
||||
The "direct imports, not barrels" rule, and the whole `optimizePackageImports` lever behind it, is
|
||||
**inert in this repo** — measured, then explained.
|
||||
|
||||
`@homarr/ui` is the largest barrel in the repo at 111 importers, and it is **not eligible**: Next's
|
||||
barrel optimiser only rewrites files that consist purely of re-exports, and `packages/ui/src/index.ts`
|
||||
also defines a runtime `uiConfiguration` value. Same for the other workspace barrels.
|
||||
Seven Mantine entry points were missing from `optimizePackageImports`: `dates` (13 files), `dropzone`
|
||||
(12), `charts` (10), `spotlight` (7), `form` (4), `notifications` (3), `tiptap` (1). Adding all seven
|
||||
and rebuilding produced a client bundle that was **byte-for-byte identical** — 482 files, 18050.7 KiB
|
||||
in both arms, down to the individual chunk hashes.
|
||||
|
||||
Adding the seven Mantine entry points is a one-line change, but it is left undone rather than guessed
|
||||
at: it needs two production builds and a first-load-JS comparison, and everything else in this work
|
||||
that shipped without a measurement was later found to be wrong. Recorded in
|
||||
[NEXT-STEPS.md](./NEXT-STEPS.md) instead.
|
||||
Identical output including hashes looks like a cached build, especially with
|
||||
`turbopackFileSystemCacheForBuild` enabled, so it was checked instead of reported. The Next.js docs
|
||||
settle it: *"This is not needed when using Turbopack. Turbopack automatically analyzes and optimizes
|
||||
imports without requiring this configuration."* This app builds with Turbopack — the build banner says
|
||||
so — and the config is dead weight.
|
||||
|
||||
Which also disposes of the sub-question underneath it. `@homarr/ui` is the largest barrel in the repo
|
||||
at 111 importers, and I had noted it as ineligible because Next's barrel optimiser only rewrites pure
|
||||
re-export files while `packages/ui/src/index.ts` also defines a runtime `uiConfiguration`. True, and
|
||||
irrelevant: Turbopack does not use that optimiser and tree-shakes the barrel regardless.
|
||||
|
||||
Measuring first-load JS per route was not possible the usual way, incidentally: Next 16 + Turbopack
|
||||
prints no size columns in the route table and emits no `app-build-manifest.json`. Total bytes under
|
||||
`.next/static/chunks` is the substitute.
|
||||
|
||||
### `data = []` defaults: declined, with the reasoning
|
||||
|
||||
|
||||
Reference in new issue
Block a user