Skip to content

perf: split shared Vue/@nextcloud/vue chunks (~47 MB -> ~24 MB widget JS)#315

Merged
rubenvdlinde merged 1 commit intodevelopmentfrom
perf/widget-bundle-size
May 5, 2026
Merged

perf: split shared Vue/@nextcloud/vue chunks (~47 MB -> ~24 MB widget JS)#315
rubenvdlinde merged 1 commit intodevelopmentfrom
perf/widget-bundle-size

Conversation

@rubenvdlinde
Copy link
Copy Markdown
Contributor

Mirror of the same fix that just landed on pipelinq. Each procest widget was inlining its own framework copy; now extracted into shared chunks loaded once.

Bundle sizes after npm run build

Bundle Before After
procest-main.js ~9 MB 4.73 MB
procest-settings.js ~6 MB 3.35 MB
procest-<each>Widget.js ~6.7 MB 3.00 MB
procest-shared-nc-vue.js 2.79 MB (loaded once)
procest-shared-vendor.js 0.33 MB (loaded once)

Total widget JS on /apps/mydash/: ~47 MB → ~24 MB cold cache; per-widget delta only on warm cache.

Validation

  • Built locally with NODE_OPTIONS=--max-old-space-size=8192 npm run build
  • Reloaded /apps/mydash/ and confirmed shared chunks load before per-widget bundles ✓
  • Console: same 11 baseline errors (pre-existing procest store-registration errors), no new errors

Test plan

  • CI build passes
  • Open /apps/mydash/, confirm procest widgets render (cases overview, my tasks, etc.)

Each procest widget entry was inlining its own copy of Vue,
@nextcloud/vue, @conduction/nextcloud-vue, pinia and the
material-design-icon set, costing ~6.7 MB per bundle. With 7 widget
entries that compounded to ~47 MB of duplicated framework JS attached
to the dashboard.

Webpack 'optimization.splitChunks' now extracts two stable-filename
shared chunks (one for Vue + lightweight deps, one for the heavier
@nextcloud/vue surface) so each widget keeps only widget-specific
code. The shared chunks load once on the page and are cached
indefinitely across navigations.

Each widget's PHP load() now also Util::addScript()s the two shared
chunks. Util::addScript dedupes by (app, file), so even with mydash
eagerly loading every widget the shared chunks emit once.

After 'npm run build' on the latest @nextcloud/vue:

  procest-shared-nc-vue.js  : (new)        2.79 MB
  procest-shared-vendor.js  : (new)        0.33 MB
  procest-main.js           :  9 MB    →   4.73 MB
  procest-settings.js       :  6 MB    →   3.35 MB
  procest-<each>Widget.js   : 6.7 MB   →   3.00 MB

Total widget JS on /apps/mydash/ drops from ~47 MB to ~24 MB on cold
load and to per-widget delta on warm cache. Validated locally via
mydash page load; no new console errors versus baseline.
@rubenvdlinde rubenvdlinde merged commit c3f5814 into development May 5, 2026
10 of 15 checks passed
@rubenvdlinde rubenvdlinde deleted the perf/widget-bundle-size branch May 5, 2026 06:10
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

Quality Report — ConductionNL/procest @ 7243bfa

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

Quality workflow — 2026-05-05 06:12 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