This article is part of the Ionic Framework / Capacitor / Stencil Advent Calendar 2021 Advent Calendar 2021, Day 1.
For Ionic/Angular performance tuning, you cannot avoid optimizing module splitting. As an extreme example, consider a project with no module splits versus one where every page and component is split out.
Understanding What Module Splitting Means
In Angular, pages, components, services, directives, and so on are all registered in ngModules. An Angular project consists of one or more ngModules, with pages and components underneath them.
Services work even if you do not register them in an ngModule when you specify
providedIn: 'root', because that makes them behave as root injectors.
Besides modules created to register shared components and directives (often called a sharedModule), modules usually have routing, and lazy loading is triggered when the user navigates to the matching URL.
{
path: 'tabs',
loadChildren: () => import('./tabs/tabs.module').then((m) => m.TabsPageModule),
},
That is exactly what this does: navigating to the tabs path loads TabsPageModule.
A Project with No Module Splits
What happens in a project with no module splits at all? In short, the initial bundle is too large and the first paint is slow.
I have an Ionic/Angular project I built ages ago and never maintained:
Take a look. It is laughably slow. Module splitting did not exist in Angular back then, so everything lives in one module (that is not the only reason it is slow, but it is a big one).
"@angular/core": "2.0.0-rc.4",
"ionic-angular": "2.0.0-beta.11",
A fossil, basically. Single-page applications render with JavaScript, so from the beginning people worried about initial bundle size and slow first paint. Module splitting is recommended today.
A Project Where Everything Is Split into Modules
Is splitting everything into tiny modules the answer? It is better than no splits, but it can hurt how the app feels to use.
I said earlier that lazy-loaded modules load when the user navigates to the matching URL. In other words, the user goes to that URL, module loading starts, and the page appears when loading finishes. Concretely, let us look at module-load delay from Preloading modules in Ionic v4.
First, when there is no delay from module loading:

Selecting a page starts navigation immediately. Next, when module loading causes delay:

After you tap, loading for that module starts, and navigation begins only when loading completes—you can see the lag.
Develop with Module Load Timing and Size in Mind
Running ionic g pg with Ionic CLI splits every page into its own module, so many projects end up fully split by default—but that can hurt user experience.
What matters is being conscious of when modules load and how large they are.
For example, in a tabs-based project, you might put each tab's features in one module, and rarely used features (especially modals) in separate modules. Then you can sketch a story in your head: "This much loads initially; loading the next module when the user taps here makes sense."
For example, here is the folder layout of tipsys, which I develop—each folder has one module.

So for the timeline folder, for example, it contains components, pages, and services like this:

If you are building at a similar scale, think once about what module size works for you.
Closing
For module splitting, Building Mobile Apps with Ionic (Angular Edition) also covers this on page 158, "Let's Combine Modules." If you are unsure how to proceed, that is a good reference.
See you next time.