Skip to content

perf(build): port webpack production build optimizations from Codeberg PR #108 - #2061

Open
SudoThijn wants to merge 1 commit into
mainfrom
hotfix/performance
Open

perf(build): port webpack production build optimizations from Codeberg PR #108#2061
SudoThijn wants to merge 1 commit into
mainfrom
hotfix/performance

Conversation

@SudoThijn

@SudoThijn SudoThijn commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Ports the npm run build performance work from Codeberg PR #108 (originally landed against development) onto hotfix/performance / main. Skips the IntegrationDashboardWidget.php hunk — that file belongs to an integration-dashboard feature that only exists on development and hasn't merged to main yet, so it comes along naturally on the next merge.
  • Minify with esbuild instead of Terser (native Go minifier, no per-chunk Node AST / worker-process overhead).
  • Disable source maps and the in-memory webpack cache in production (a one-shot build never reuses the cache; it only inflated peak RAM).
  • Split shared vendor deps (vue, @nextcloud/vue, pinia, the local nextcloud-vue source, …) into a dedicated openregister-vendor chunk via splitChunks, instead of duplicating them into every entry.
  • Add ScriptManifestLoader (+ unit tests): since entries are no longer self-contained after splitting, this reads the build-emitted js/openregister-entrypoints.json manifest and enqueues every initial chunk for an entry, falling back to the legacy single script if the manifest is missing (dev builds, older builds). Wired up in templates/index.php, templates/settings/admin.php, FilesSidebarListener, and MailAppScriptListener.
  • Bugfix: the @nextcloud/dialogs webpack alias was missing the $ exact-match suffix used by every other alias in this file, so subpath imports like @nextcloud/dialogs/style.css got rewritten to a nonexistent literal path instead of resolving through the package's exports map — this made production builds fail outright on main before this PR. Confirmed pre-existing (unrelated to this change).

Baseline vs. after (production npm run build)

Metric Before After Δ
Build time ~52s ~21s −60%
Peak RAM (whole build process tree) ~8.3 GiB ~2.24 GiB −73%
js/ output 92M / 58 files 17M / 15 files −82%

Applies the same production build changes previously done on the
development branch: minify with esbuild instead of Terser (native Go
minifier, no Node worker overhead), drop source maps and the in-memory
webpack cache in production, and split shared vendor deps into dedicated
chunks via splitChunks instead of duplicating them per entry.

Since entries are no longer self-contained after splitting, add
ScriptManifestLoader (+ unit tests) to enqueue every initial chunk for an
entry from the build-emitted js/openregister-entrypoints.json manifest,
falling back to the legacy single script if the manifest is absent. Switch
all script-loading call sites (main index, admin settings, files sidebar,
mail sidebar) to it.

Also fixes a pre-existing bug that made production builds fail outright:
the '@nextcloud/dialogs' webpack alias was missing the '$' exact-match
suffix used by every other alias in this file, so subpath imports like
'@nextcloud/dialogs/style.css' were rewritten to a literal path instead of
resolving through the package's exports map.

Baseline vs after (production npm run build): ~52s -> ~21s build time,
~8.3GiB -> ~2.24GiB peak RAM, js/ output 92M/58 files -> 17M/15 files.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ c8f2ad3

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 147/147
npm ✅ 525/525
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-07-24 11:21 UTC

Download the full PDF report from the workflow artifacts.

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