perf: split shared Vue/@nextcloud/vue chunks across entry-points#119
Merged
Conversation
Mirror of the same fix that landed on pipelinq and procest, applied to docudesk's main / settings / dashboard entry-points. Each entry was inlining its own copy of Vue, @nextcloud/vue, @conduction/nextcloud-vue, pinia and the material-design-icon set, costing ~3 MB of duplicated framework JS per bundle. Webpack 'optimization.splitChunks' now extracts two stable-filename shared chunks. Each entry keeps only entry-specific code; the shared chunks are loaded once per page and cached across navigations between docudesk's own pages. Per-widget delta (currently 1.89 MB for docudesk-dashboard.js, was 3.63 MB) is what every future widget will add on top of the shared baseline. The two existing dashboard widget classes call Util::addScript() for the two shared chunks before the dashboard bundle. Util::addScript dedupes by (app, file) so emitting both widget classes' scripts on the same render still produces each chunk in the HTML exactly once. After 'npm run build': docudesk-shared-nc-vue.js : (new) 2.71 MB docudesk-shared-vendor.js : (new) 0.31 MB docudesk-main.js : 6.06 MB → 3.37 MB docudesk-settings.js : 5.97 MB → 3.30 MB docudesk-dashboard.js : 3.63 MB → 1.89 MB Note the trade-off on /apps/mydash/: the dashboard payload increases from 3.63 MB to 4.91 MB on cold cache (+1.28 MB) because the shared chunks are new bytes. On warm cache the user already has the shared chunks and only the 1.89 MB widget delta loads. The pattern primarily pays off as docudesk grows additional dashboard widgets — each new widget then adds only ~1-2 MB of widget-specific code on top of the shared baseline that's already cached. Validated locally via mydash page load; no new console errors versus baseline.
Contributor
Quality Report — ConductionNL/docudesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 108/108 | |||
| npm | ✅ | ✅ 529/529 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/10 statements)
Quality workflow — 2026-05-05 06:20 UTC
Download the full PDF report from the workflow artifacts.
9 tasks
rubenvdlinde
pushed a commit
that referenced
this pull request
May 19, 2026
PR #119 split Vue / @nextcloud/vue / @conduction/nextcloud-vue / pinia / vue-material-design-icons into shared chunks (docudesk-shared-vendor.js, docudesk-shared-nc-vue.js), and updated the dashboard-widget loaders to addScript them. The two page templates (templates/index.php and templates/settings/admin.php) were missed: only the per-page entry was loaded, so webpack's runtime sat forever in chunkOnLoad waiting for chunks that never arrived. Result: blank Anonymisation page, blank admin settings page, blank main app — no console error, just nothing. Add the two shared chunks to both templates so the entry's chunkOnLoad callback resolves. Order matters only to the extent that the shared chunks self-register on a shared global before the entry runs; loading them first is the conventional path. Pipelinq and procest received the same split-chunks treatment in #119 and likely have the same broken template — worth a cross-check.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Same pattern that just landed on pipelinq and procest. Extracts shared Vue +
@nextcloud/vue+ pinia into stable-filename chunks so each entry keeps only entry-specific code.Bundle sizes after
npm run builddocudesk-main.jsdocudesk-settings.jsdocudesk-dashboard.jsdocudesk-shared-nc-vue.jsdocudesk-shared-vendor.jsTrade-off on
/apps/mydash/Docudesk only has one widget bundle (
docudesk-dashboard.js), so unlike pipelinq/procest there is nothing to dedupe at the widget level today. On the mydash dashboard page the docudesk payload actually grows from 3.63 MB to 4.91 MB on cold cache (+1.28 MB) because the shared chunks are new bytes that previously did not exist. On warm cache (a returning user, or a user who has visited any docudesk page first) the shared chunks are already cached and only the 1.89 MB widget delta loads (-1.74 MB net).Shipping this anyway because:
/apps/docudesk/and/apps/docudesk/adminbenefit immediately from the cross-page caching.Validation
NODE_OPTIONS=--max-old-space-size=8192 npm run build✓/apps/mydash/and confirmed shared chunks load beforedocudesk-dashboard.js✓Test plan
/apps/mydash/, confirm docudesk widgets render (file entities, anonymization)/apps/docudesk/, confirm main app renders