Skip to content

Load each plugin section and core screen group on demand - #43

Merged
aevnsvi merged 3 commits into
mainfrom
split-bundle-by-section
Nov 8, 2026
Merged

aevnsvi merged 3 commits into
mainfrom
split-bundle-by-section

Conversation

@aevnsvi

@aevnsvi aevnsvi commented Nov 8, 2026

Copy link
Copy Markdown

What changed

Every plugin section and core screen group is now fetched when it is first shown instead of being part of the entry bundle.

  • Chunks: file, deb, rpm, python, ansible, users, groups, roles, tasks, status and signature-keys. The login page, the about page, the placeholders, the "plugin not installed" page, the not-found page and the loading page stay in the entry.
  • lazyScreen(load) wraps React.lazy: the loading page shows while the code arrives, and a screen whose code cannot be fetched (a tab left open across a new deployment, where every chunk file name changes) shows an error state with a Reload button instead of the router's error page. A rejected import is remembered by React, so the button reloads the page rather than retrying the import.
  • The lazy loading is done in the screen components, inside the route guard, and not with the router's route lazy: a signed-out user, or a server without the plugin, never requests the section code.
  • src/containers/index.ts is removed. A barrel that re-exports every screen keeps all of them in the entry bundle, even when they are also imported lazily, so each screen is imported from its own file.
  • package.json gets a sideEffects list (*.css, *.scss, the entrypoint, l10n and darkmode, the only side-effect-only imports in src/), so unused re-exports of the component barrels are dropped from the build.
  • The layout route is part of the entry. It used to be a lazy route, which left the build commit stamp outside the script index.html names and made the real initial load larger than the entry looked.
  • ListErrorState takes an optional button label.

Sizes (production build, gzip level 9)

Before After
Entry JS (App.*.js) 346,876 242,923
Entry CSS (App.*.css) 227,396 205,226
Layout chunk, loaded on every first render (JS + CSS) 8,302 + 6,276 in the entry

Section chunks (JS gzip): ansible 14,189, deb 5,383, file 5,244, groups 7,830, python 7,147, roles 6,625, rpm 5,852, signature-keys 4,126, status 4,877, tasks 6,669, users 9,361, plus shared vendor chunks.

The build now reports a few "Conflicting order" warnings between PatternFly component stylesheets that are shared by several chunks. The same rules are all present in the entry stylesheet.

How it is tested

  • lazy-screen.test.tsx: the loading page then the screen with its props; a rejected load shows "This screen could not be loaded" with a Reload button; pressing Reload calls window.location.reload once.
  • app-routes.test.tsx: the root route is static; deep links to the status screen (signed out) and to a file section screen render once their code has loaded. The existing route and gate tests pass unchanged against the lazy screens.
  • e2e/crawl/routes.test.mjs still parses the route table, and the message catalogs are refreshed.
  • Local gate (tests, typecheck, prettier, eslint, ls-lint, public-content guard) and a production build are green; the build emits the eleven chunks and the entry script carries the full build commit.

- lazyScreen fetches a screen when it is first shown, with the loading page
  while it arrives and a Reload state when its code is gone (for example in a
  tab left open across a new deployment)
- the six file screens become one lazily loaded chunk
- src/containers/index.ts is removed: a barrel re-exporting every screen keeps
  them all in the entry bundle, so each screen is imported from its own file
- package.json lists the modules with side effects so unused re-exports of
  component barrels can be dropped from the build
- deb, rpm, python, ansible, users, groups, roles, tasks, status and
  signature keys each become one lazily loaded chunk next to file
- the layout route is part of the entry instead of a lazy route, so the
  files index.html names are the whole initial load and the build commit
  stamp stays in the entry script
- the login page, the about page, the placeholders, the not-installed page
  and the not-found page stay in the entry
@aevnsvi
aevnsvi merged commit 3c3577d into main Nov 8, 2026
6 checks passed
@aevnsvi
aevnsvi deleted the split-bundle-by-section branch November 8, 2026 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant