Lazy JavaScript per route
This is what a first visit fetches on top of the initial bundle, from the QA build. Before means after step 1. MB means a million bytes, the same unit the plan uses.
| Route | Before | After | Commit |
|---|---|---|---|
/creators-home | 4.45 MB | 1.29 MB | 0beb9e0e04 |
Creator sub pages, /:user/:subPage and the white-label root sub pages | 4.41 MB | 1.36 MB | 0beb9e0e04 |
Marketing pages such as /athletes and /music-artists | 4.40 MB | 2.15 MB | 0beb9e0e04 |
Comparison pages, /topfan-vs-* | 4.40 MB | 2.16 MB | 0beb9e0e04 |
Marketing pro pages, /apps/* | 4.42 MB | 2.19 MB | 0beb9e0e04 |
/, /home and its category pages, /search-result | 4.44 MB | 3.22 MB | dd02f5c329 |
The 15 entries that still load SharedModule grew by at most 8 KB each, the dashboard being the largest. The initial bundle grew by 2.3 KB, from 7,131,151 to 7,133,428 bytes. The code inside it actually shrank by 586 bytes. esbuild split the shared code into 8 more small chunks, and each chunk adds its own import and export lines. I think that's fine for now, and it should go back down once SharedModule is gone.
Why step 2 became two commits
The plan counted about 22 SharedModule pieces for this step. That number only covered the marketing layouts. The page behind / also renders ProfileComponent on white-label sites and SearchedPostListComponent on the search page, and those two pull in the post card and everything around it. Converting both brought the step to 54 SharedModule pieces plus the 55 marketing components. I split it so the marketing pages and the home page can be reviewed apart.
Commit 0beb9e0e04: make MarketingPageSharedModule a list of standalone pieces
What changed
- The 55 components
MarketingPageSharedModuledeclared are standalone now. Each imports what the Angular compiler matched in its template and nothing else. MarketingPageSharedModulehas no declarations and no longer imports SharedModule. It lists the same pieces in its imports and keeps its exports list unchanged, so anything still importing it gets the same components./creators-homeand the sub page view import their layout components directly and no longer use the module.- Those components needed 27 SharedModule pieces, which became standalone and moved from SharedModule's declarations to its imports. They include comments, the like and share bar, poll options, the four store detail views, unlock content, fundraiser progress, the @mention and #hashtag inputs, and pipes and directives such as
PostLiked,ConvertDate,CurrencyConversionPipe,UserTimeZoneandTranslateDirective. SharedModule still exports all of them. - Three store layout items, for event tickets, feed content and portfolio items, are no longer bundled.
MarketingPageSharedModuleimported them but never exported them, and no template uses them. The files are still in the repo. - Five components lose ngx-intl-tel-input's
NativeElementInjectorDirective: comments, the comparison layout, the newsletter layout, fundraiser progress and merchandise details. None of their templates has a phone input.
How I checked it
| Check | Result |
|---|---|
| Compiled template dependencies against step 1 | 648 of 656 components match. Five lose only the phone directive, as listed above. The other three are the unused store layout items, which the compiler no longer sees. |
| QA and development builds | Both pass. QA has the same 42 warnings as base. Development has none. |
| Component definitions in a browser | Loaded 9 entry chunks, including the marketing, comparison, pro, profile and white-label cover page chunks, and walked every reachable component. All dependencies resolve and there are no page errors. |
| Server rendering, 65 URLs | The step 1 URLs plus every marketing and comparison page, the pro pages and a creator profile with sub pages. All match step 1 once the compare script masks bundle hashes, style scope IDs and the hydration state. On the first run /creators/login differed. It matched on the rerun, so the QA data changed between the two requests. |
| Logged-out browser run, main site | 10 routes, including /, /home, /creators-home, two marketing pages and two comparison pages. Same components after hydration, no page errors. |
| Logged-in browser run, main site | 12 routes. Most redirect the test creator to its white-label setup on both builds. Same components on all of them after a 15 second wait. |
| Logged-in browser run, white-label site | 7 routes, including /, the creator profile, a sub page and the white-label editor with its full marketing preview. Same components, no page errors. Clicking the comment count on a profile post opens the comments on both builds. |
| ESLint on the changed files | 12 errors, down from 96. The 84 gone are prefer-standalone. The 12 left exist on base. |
The first browser runs used a 9 second wait and showed differences in both directions. Sometimes base was further along, sometimes this commit. The QA API was slow that hour. With 15 to 20 seconds and both builds loaded side by side, every route matched.
Commit dd02f5c329: stop the home and search pages loading SharedModule
What changed
- The promotional landing, promotional, promotional detail and search result components import what their templates use. That covers
/,/homeand its category pages, and/search-result. Two of them stop importingMarketingPageSharedModuletoo. - 27 more SharedModule pieces became standalone and moved to SharedModule's imports. The big ones are
ProfileComponent,SearchedPostListComponentandPostCardComponentwith its locked and sensitive overlays, stats and footer. The rest are the profile sidebar, followers and followings, the welcome video post, the sponsored ad, the event countdown, the badge, user groups, giveaway, fund and user type modals, the audio slider directive, and eight pipes. BlockedUserStatusis one of those pipes. It has an@Injectable()decorator under its@Pipe, and my scan for NgModule pieces missed it. The compiler caught it, and I converted it by hand. Two components still provide it as a service, which works the same for a standalone pipe.ProfileComponentloses the phone directive. Its template has no phone input.
How I checked it
| Check | Result |
|---|---|
| Compiled template dependencies against the previous commit | 652 of 653 components match. ProfileComponent loses only the phone directive. |
| QA and development builds | Both pass. Same 42 QA warnings, none in development. |
| Component definitions in a browser | 6 entry chunks, including /, the profile, the dashboard and post detail. No problems, no page errors. |
| Server rendering, 70 URLs | The 65 above plus /home/music, /home/music/rock and three search result URLs. 67 match the same way. The other three are explained below. |
| Logged-out browser run, main site | 8 routes, including /, /home/music/rock, two search result pages and a creator profile. Same components after hydration, no page errors. |
| Profile tabs, logged out | The posts tab shows the same components on both builds. Followers and Following show the same sign-in prompt on both. |
| Logged-in browser run, white-label site | 7 routes. / shows the creator profile with posts on both builds, with the same components. The comments open on a profile post. |
| ESLint on the changed files | 2 errors, down from 29. Both exist on base. |
The three server rendering differences were /help-faq, /perfectcrew and /perfectcrew/store. This commit doesn't touch /help-faq, and on a refetch both builds returned the same page. The two profile pages differ only in their list of chunks to preload, because this commit splits the JavaScript into different chunks. I also compared the hydration state the compare script masks. It differs only in template numbers, since the server keeps counting templates across requests. With those renamed in order of first use, it matched exactly.
What I couldn't test. The followers and followings lists need a logged-in fan on the main site, and the only test account is a white-label creator. Those components compile to the same dependencies as before, but nobody has opened them on this branch yet. They're in the checklist.
What's still heavy
None of this is in these commits. I found it while measuring and I'd rather write it down than forget it.
/still fetches 3.22 MB. On the main site most of that isProfileComponentand the post card, which only white-label sites show there. Loading the profile withloadComponentor@deferwould move it off the main site's home page.- Every marketing page ships all 55 layouts, about 900 KB, because the full preview picks a layout per section at runtime. A
@deferblock per layout type would fetch only the layouts a page uses. comparison-layout.utils.tsimports constants from the page editor'sadd-marketing-page-sectionfolder, which adds about 107 KB of editor code to public pages. The pro contact form layout uses the dynamic form builder, which brings in PrimeNG, the timepicker and luxon.- The three unused store layout item components can be deleted.
pro-hero-layout.component.tshas aconsole.logfrom before this branch.
Verification checklist
Keep the console open. White-label checks need a creator account on its white-label site. Checks are saved in this browser.