Why every marketing page ships 54 layouts

This leftover is done. The public preview now loads only the layout ids a page shows. Measured sizes, the header exception, and the checklist for the change are in public marketing pages load only the layouts they use. The three files are in how the marketing preview loads a layout. The rest of this page is the problem as it existed after PR 10847.

leftover from after the SharedModule work implemented in the layout split notes 25 Sep 2026

What a layout is

Think of a printed magazine page. One page might have a big title photo, a quote, and a list of products. Those are different templates. In this app they are Angular components with names like hero, testimonials, store-items-grid, and comparison-full-table.

There are 55 layout ids in the catalog. The public preview has a component for 54 of them. pro-contact-form is the missing one. Creators pick from this list when they build a marketing page, a comparison page, a pro page, or a white-label cover.

What happens today

One component draws every public marketing page. MarketingPageFullPreviewComponent. It loops the page's sections. For each section it reads a layout id and switches to that component.

Angular only lets a template use a component that the parent imported. So the preview file imports all 54 classes and lists all 54 in its imports array. The switch can then render any of them. The bundler sees 54 static imports, so it puts all 54 in the same JavaScript the page downloads.

A page that uses a header, a hero, and a footer still pays for the passion grid, the portfolio album block, and the comparison table. Those files run no code on that visit. They still travel over the wire.

Which pages pay

Anything that renders through that preview component:

  • The main site's /
  • /marketing
  • The comparison pages
  • The pro pages
  • Creators-home
  • A white-label cover page

The editor that lets a creator add a section also imports the full list. That is the right call. A creator opening the picker needs every type. The waste is the public pages using the same graph.

What it cost after 10847

First-visit JavaScript after the initial bundle, from the QA build after PR 10847. MB means a million bytes, before compression. After the layout split these entries are 1.76, 0.03 to 0.86, and 0.11 to 0.21 MB. See the notes.

PageAfter 10847
Main site /2.79 MB
Marketing1.23 MB
Comparison1.23 MB
Pro2.05 MB
Creators-home1.30 MB
Sub-page view1.36 MB

Those numbers are the whole route, not layouts alone. Shared chrome sits in there too. The layouts are why the numbers stayed this high after we already took SharedModule and Profile off the home chunk.

What we would gain

The visitor would download only the layout types that page actually uses. Six types on the page means six layout files, plus the preview shell. The other 48 stay on the server until some other page needs them.

I will not invent a megabyte number. We have not split the files yet, so we have not measured the leftover. The direction is clear.

WinWho feels it
A thin page stops paying for layouts it never shows First visit to home, marketing, comparison, pro, creators-home, and a cover page
A second marketing URL can reuse layouts the first page already fetched Someone who goes from home to a comparison page that shares a hero and a header
A kitchen-sink page that uses 20 types shrinks less Demo pages that stacked most of the catalog. That is expected.
The editor can keep all 54 Creators. Their first open of the CMS still has every block in the picker.

The win is first-visit JS. It is not a new feature and it is not a visual redesign. If a page looks different, the change is wrong.

How the fix would work

Stop importing the 54 classes at the top of the preview file. Keep a map from layout id to a dynamic import(). When the page knows its sections, start those imports together. Render each finished class with ngComponentOutlet.

The server has to wait for those imports before it writes HTML. We already did this for the white-label profile fallback, with PendingTasks. Skip that and the first HTML is missing <app-hero-layout>. The browser then fills it in. Search engines and the first paint see a hole. @defer has the same hole. It is the wrong tool on these public pages.

Verification checklist

After a change, the page must look the same and the unused layout files must stay off the wire. Keep the network panel and the console open. Checks are saved in this browser.

0 of 0 checked

High The page still looks like itself

High The unused layouts stay off the wire

Medium Clicks still work

Low The editor is unchanged