First-visit JavaScript
What a first visit fetches on top of the initial bundle, from the QA build. Sizes are minified bytes before compression. Before means after PR 10845. MB means a million bytes.
| Route | Before | After |
|---|---|---|
| The monetize routes file itself | 3.20 MB | 12.7 KB |
/monetize/subscription | 3.20 MB | 0.53 MB |
/monetize/merchandise | 3.20 MB | 41 KB |
/monetize/downloadable | 3.20 MB | 21 KB |
/monetize/newsletters | 3.20 MB | 0.19 MB |
/monetize/newsletters/add | 3.20 MB | 1.53 MB |
Main site / | 3.22 MB | 2.79 MB |
| The post-price dialog, counted alone | 123 KB | 118 KB |
A first visit to a monetize child also downloads the 12.7 KB parent. Add-newsletter stays large because that page still owns the text editor. The initial bundle grew by 3.2 KB. The build now has 341 JavaScript files instead of 276, because each monetize page is its own entry, and so are ProfileComponent and the camera modal. No route loads SharedModule.
Commit 3e564a2ca2: load each monetize page only when its route opens
What changed
MonetizeContainerComponentstays a static import. The shell is needed as soon as/monetizeopens.- Every page, including nested nft, experience, course, and discount-code children, uses
loadComponent. - Portfolio still uses
loadChildren. Advertisements still only redirects topreferences. Guards anddelegatePathdata are the same.
How I checked it
| Check | Result |
|---|---|
| Compiled template dependencies against PR 10845 | 645 of 646 components match. The one change is the home landing page, from the next commit. |
| QA and development builds | Both pass. QA has the same 42 warnings as before. |
| Logged-in white-label walk | Listing pages and the add forms for newsletters, events, merchandise, subscriptions, courses, experiences, nfts, vip offers, and discount codes land on the same components. The first pass of add-downloadable was still loading at 9 seconds. At 20 seconds it matches. |
| ESLint on the routes file | Clean. |
Commit 367e633593: keep ProfileComponent off the main site home chunk
What changed
PromotionalLandingComponentno longer importsProfileComponentas a value. The type-only import is erased.- White-label builds start
import()in the constructor and keep aPendingTasksentry open until it finishes, so SSR still emits<app-profile>on the profile fallback. - The template uses
ngComponentOutletand passesuserId. A static import, or@defer, would either keep the profile on the main home chunk or drop it from white-label SSR.
Without PendingTasks, the first white-label SSR of / came back 80 KB lighter and had no <app-profile>. The import finished after the server decided it was done. The task list is what makes Angular wait.
How I checked it
| Check | Result |
|---|---|
| Compiled template dependencies | The landing page lost ProfileComponent and gained NgComponentOutlet. Every other component matches. |
Main site / network | No app-profile in the document, and no profile file in the JavaScript the page fetched. |
White-label / SSR | Same <app-profile> and skeleton as PR 10845, 252 KB of HTML either side. |
| Logged-in white-label home | Redirects to /perfectcrew and renders the profile, sidebar, and welcome video. Text length drifted by a few dozen characters. Tag counts matched after 20 seconds. |
| Server rendering, 145 URLs, then 5 again after the pending-task fix | All match PR 10845. |
Commit 6db341b485: open the post-price camera modal only when it is used
What changed
openCameraTestModalnowimport()sCameraModalComponentbeforeBsModalService.show.- The image cropper stays in the decorator. The template still renders it behind
*ngIf.
This is cleanup, not a fix for the 4 KB leftover from PR 10841. Counted on top of the dashboard, the dialog still fetches about 65 KB, almost all of it post-price.component.ts, add-lock, and custom-input-list. Those files were already in the leftover after 10841. Pulling the camera out of the static graph drops the dialog-alone entry by 5 KB, because the camera is no longer in that leftover. It does not shrink the extra-beyond-dashboard set. That set even grew by 1 KB from one more chunk.
How I checked it
| Check | Result |
|---|---|
| Post-price template dependencies | Unchanged. The camera was never in the template. |
| Article and video lock dialogs | Both open with the same inputs, text, and child tags. Nothing was saved. |
| ESLint on the dialog | Clean. |
Commit cb2893c092: don't open the camera after the lock dialog closes
What changed
- Only one camera-chunk import runs at a time. A second click during that wait is ignored.
- After the import, the modal opens only if that click is still the current request.
cancelModalandngOnDestroydrop the request, so a late import does not callshoworgetUserMedia.- A failed import shows the existing error string and clears the pending flag so the next click can try again.
How I checked it
| Check | Result |
|---|---|
| Cancel during a delayed import | Zero camera modals. |
| Two clicks during that delay | One camera modal. |
| One click with the chunk already ready | One camera modal. |
| Failed import, then a later click | The pending flag clears. The later click opens one. |
| ESLint on the dialog | Clean. |
The webcam button only exists on an active livestream's lock dialog. I did not go live to click it in the running app.
What's left
AppModuleandAppServerModuleare the last NgModules.- Every marketing page still ships all 55 section components.
- The post-price leftover after dashboard is still
custom-input-listsitting with add-lock, not unused decorator imports.
Verification checklist
Use a creator account on its white-label site. Keep the console open. Checks that end in save change real data, so use a test account. Checks are saved in this browser.