Ionic Standalone & ESBuild increase in initial bundle size. Lazy loaded components included in initial Bundle

I’m currently working on a migration from IonicModule with Webpack to Ionic Standalone Components with ESBuild.
I expected the initial bundle size to shrink, since some components are only required in specific lazily loaded routes.
However, the initial bundle exploded in size (1.08MB → 1.81MB) as it contains ionic standalone components that are not needed in the initial bundle.

For example:

  • We have a lazy loaded admin ui
  • The admin ui is the only place where the ion-datetime component is used.
  • Nevertheless the ion-datetime component is included in the initial bundle, downloading for 99% of the users of the app who will never use it.
  • Removing the routing to the component → ion-datetime is not included in the initial bundle anymore. Which confirms that this one lazy loaded component triggers the build to include it in the initial bundle.

Project setup

Packages:

  • @ionic/angular: 8.4.1
  • @angular: 19
  • "builder": "@angular-devkit/build-angular:application",

Routing:

main.ts:

        provideIonicAngular({
            innerHTMLTemplatesEnabled: true,
            experimentalCloseWatcher: true,
        }),
        provideRouter(APP_ROUTES),



export const APP_ROUTES: Routes = [
...
    { path: "admin", loadChildren: () => import("./admin/admin.routing").then((m) => m.ADMIN_ROUTES) },
...
];

admin.routing.ts:

export const ADMIN_ROUTES: Routes = [
...
            {
                path: "orders-payments-invoices",
                loadComponent: () =>
                    import("./orders-payments-invoices/admin-orders-payments-invoices.page").then(
                        (m) => m.AdminOrdersPaymentsInvoicesPage, // ion-datetime is used here exclusively
                    ),
            },
...
];

Generated initial bundle chunks

npm run: "analyze:bundle": "ng build --configuration=production --stats-json && start www && start https://esbuild.github.io/analyze/",

The generated stats.json is then analyzed with the esbuild analyzer tool:

Lazy loaded ion-datetime

The ´ion-datetime` is included in the initial bundle, although it is only needed on ONE lazy loaded route. Generally it looks like all standalone components from ionic are included in the initial bundle regardless of where they are used.

No ion-datetime usage

Commenting out the loadChildren: ...AdminOrdersPaymentsInvoicesPage part, leads to the ion-datetime being correctly excluded:

Question

Is there any way to configure Ionic, Angular, ESBuild to make sure that components that are only required for some lazy route along the way are not part of the initial bundle?

Update 1:

I just tried the same things with the old webpack builder @angular-devkit/build-angular:browser, and I am noticing the same behavior, the ion-datetime is included in the main.js initial chunk as well.

Is this how it is intended to work? If yes, what are the advantages of using the standalone components?
Is the tree shaking for standalone components only reducing the overall build size, but increasing the initial bundle size? In that case, using standalone components is a worse when targeting the browser with an web app :frowning:

1 Like