Monetize pages load one at a time, and home no longer ships Profile

Opening subscriptions no longer downloads the event calendar, the newsletter editor, and every other monetize form. The main site's / no longer downloads ProfileComponent. White-label homes that still fall back to a profile load it with import() and wait for that import during SSR. The post-price camera modal loads when someone clicks it. That last change does not undo the 4 KB leftover from PR 10841.

branch t3code/lazy-monetize-home-profile on top of 81c5e10824, PR 10845 merged Follow-ups 2, 3, and 4 of what's left 4 commits, PR 10847

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.

RouteBeforeAfter
The monetize routes file itself3.20 MB12.7 KB
/monetize/subscription3.20 MB0.53 MB
/monetize/merchandise3.20 MB41 KB
/monetize/downloadable3.20 MB21 KB
/monetize/newsletters3.20 MB0.19 MB
/monetize/newsletters/add3.20 MB1.53 MB
Main site /3.22 MB2.79 MB
The post-price dialog, counted alone123 KB118 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

1 file, +232 −193

What changed

  • MonetizeContainerComponent stays a static import. The shell is needed as soon as /monetize opens.
  • Every page, including nested nft, experience, course, and discount-code children, uses loadComponent.
  • Portfolio still uses loadChildren. Advertisements still only redirects to preferences. Guards and delegatePath data are the same.

How I checked it

CheckResult
Compiled template dependencies against PR 10845645 of 646 components match. The one change is the home landing page, from the next commit.
QA and development buildsBoth pass. QA has the same 42 warnings as before.
Logged-in white-label walkListing 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 fileClean.

Commit 367e633593: keep ProfileComponent off the main site home chunk

2 files, +28 −6

What changed

  • PromotionalLandingComponent no longer imports ProfileComponent as a value. The type-only import is erased.
  • White-label builds start import() in the constructor and keep a PendingTasks entry open until it finishes, so SSR still emits <app-profile> on the profile fallback.
  • The template uses ngComponentOutlet and passes userId. 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

CheckResult
Compiled template dependenciesThe landing page lost ProfileComponent and gained NgComponentOutlet. Every other component matches.
Main site / networkNo app-profile in the document, and no profile file in the JavaScript the page fetched.
White-label / SSRSame <app-profile> and skeleton as PR 10845, 252 KB of HTML either side.
Logged-in white-label homeRedirects 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 fixAll match PR 10845.

Commit 6db341b485: open the post-price camera modal only when it is used

1 file, +4 −2

What changed

  • openCameraTestModal now import()s CameraModalComponent before BsModalService.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

CheckResult
Post-price template dependenciesUnchanged. The camera was never in the template.
Article and video lock dialogsBoth open with the same inputs, text, and child tags. Nothing was saved.
ESLint on the dialogClean.

Commit cb2893c092: don't open the camera after the lock dialog closes

1 file, +54 −22

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.
  • cancelModal and ngOnDestroy drop the request, so a late import does not call show or getUserMedia.
  • A failed import shows the existing error string and clears the pending flag so the next click can try again.

How I checked it

CheckResult
Cancel during a delayed importZero camera modals.
Two clicks during that delayOne camera modal.
One click with the chunk already readyOne camera modal.
Failed import, then a later clickThe pending flag clears. The later click opens one.
ESLint on the dialogClean.

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

  • AppModule and AppServerModule are the last NgModules.
  • Every marketing page still ships all 55 section components.
  • The post-price leftover after dashboard is still custom-input-list sitting 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.

0 of 0 checked

High Monetize pages that used to share one chunk

High Home profile fallback

Medium Post-price camera