Skip to content

finding(console): metadata-admin's 172,651 B eager closure is held by a REGISTRY CONTRACT, not by chunking — registerAppComponent takes a component value #6776

Description

@os-sales

Found while implementing objectui#6681, which measured all four of AppContent's
non-single-file lazy() surfaces and freed the two that were removable. This records the
one that was NOT, so the 172,651 B does not leave the backlog when objectui#6681 closes.
Filed unassigned, recording only. Observational: nothing is broken and
pnpm check:eager-closure PASSES (3171.5 KB of a 3222.7 KB ceiling after objectui#6681).

What was measured

On b98352a15, from apps/console/dist/eager-closure.json (files[] IS the eager set)
and the emitted chunks' own module lists — never a source-level search (objectui#6680).

assets/metadata-admin-*.js is 172,651 B gzipped, 144 modules, EAGER — 5.4% of the
whole console eager closure and more than three times its 51.1 KB of headroom. Every
console page load pays for it while AppContent declares its six pages lazy().

The chunk is not held by co-tenancy, which is what objectui#6681 repaired for the
marketplace routes. It is held by real static edges into
packages/app-shell/src/views/metadata-admin/index.ts, the module all six declarations
target:

eager importer what it takes why it is eager
packages/app-shell/src/index.ts eleven runtime values re-exported (registerMetadataPreview, useMetadataClient, getMetadataInspector, …) the package barrel; the console entry imports it
packages/app-shell/src/services/builtinComponents.tsx MetadataDirectoryPage, MetadataResourceRouter by value, plus PackagesPage and PermissionMatrixEditPage the barrel BARE-imports it (import './services/builtinComponents.js';) for its ComponentRegistry registrations

Decisive for anyone reaching for a chunking lever first: the six pages the declarations
name (DirectoryPage, StudioHomePage, ResourceListPage, ResourceEditPage,
ResourceHistoryPage, DiagnosticsPage) have dynamicImporters: [] in the emitted
module graph. They are reached only through the barrel's static re-exports, so no
advancedChunks group separates them from it — grouping them would emit one eager chunk
instead of one eager chunk. objectui#6681 measured that failure mode directly on the
marketplace pages and recorded it in apps/console/vite.config.ts.

Why it is a registry contract, not a bundling problem

registerAppComponent({ ref, component }) takes a component value, so
builtinComponents.tsx must have loaded the page before it can register the ref. That is
the load-bearing half: the registration itself must happen at module load, or
ComponentNavView cannot resolve metadata:directory when the first
component/... route mounts.

What is NOT load-bearing is that the value be an eagerly-imported component.
React.lazy(() => import('../views/metadata-admin/index.js').then(m => ({ default: m.MetadataDirectoryPage })))
is also a component type. Whether that is correct depends on two things this card does not
settle:

  1. whether every render site of a registry component sits inside a <Suspense> boundary
    (ComponentNavView and any host embedding the registry);
  2. whether the package barrel should go on re-exporting eleven runtime values from a
    module its own sideEffects array declares side-effectful — those re-exports are a
    published API with out-of-package consumers, and they alone keep the module eager even
    if builtinComponents.tsx is fixed.

Both are published-contract decisions rather than in-lane bundling changes, which is why
objectui#6681 pinned the surface instead of attempting it.

What this card does NOT claim

  • Not a budget regression. The closure PASSES, with more headroom than before
    objectui#6681.
  • Not that the five top-level registrations in views/metadata-admin/index.ts
    (registerBuiltinAnchors, registerDefaultMetadataSchemas, registerDatasourceResource,
    registerBuiltinPreviews, registerBuiltinInspectors) should be deleted or declared
    side-effect-free. They are load-bearing, @object-ui/app-shell's sideEffects array
    names the module for exactly that reason, and objectui#6681 added a guard in
    scripts/vite-declared-lazy-views.ts that refuses to declare it pure — proved to fire
    by ablation.

Suggested shape, if graded

Decide (1) and (2) above first; they are the card. If both answers allow it, measure what
a lazy registerAppComponent value plus a leaf-module re-export path is worth, and delete
the views/metadata-admin/index.ts line from DECLARED_LAZY_VIEWS_STILL_EAGER — the
ledger's missing half fails the build until that line goes, so the win cannot be taken
silently.

Related

  • objectui#6681 — the card this was found under; the measurement, and the two chunks that
    WERE freed.
  • objectui#6680 — chunk co-tenancy: the mechanism that held the marketplace routes and
    explicitly does NOT hold this one.
  • objectui#6683 / objectui#6735 — the sideEffects array that names this module.
  • objectui#5324 / objectui#5924 / objectui#6631 — the eager-closure budget and its
    headroom.

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatchedpriority:p1

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions