Skip to content

Configuring default options for different mat components results in the entire component being in the initial bundle #31375

@wartab

Description

@wartab

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

When configuring default options for mat-components in ApplicationConfig, the entire component is being included in the initial bundle rather than being lazy-loaded along with the components that use them.

Obviously, you could load the config at every component, but that would be quite annoying.

export const appConfig: ApplicationConfig = {
  providers: [
    provideBrowserGlobalErrorListeners(),
    provideZonelessChangeDetection(),
    provideRouter(routes),
    /*{
      provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
      useValue: {
        subscriptSizing: "dynamic",
        appearance: "outline",
        floatLabel: "always",
      } as MatFormFieldDefaultOptions,
    },*/
  ]
};

Example with the app in the Stackblitz with the options commented:

Initial chunk files | Names          |  Raw size | Estimated transfer size
chunk-UP2ZEWFZ.js   | -              | 136.87 kB |                40.26 kB
main-GUD7ZPGJ.js    | main           |  78.08 kB |                19.85 kB
styles-5INURTSO.css | styles         |   0 bytes |                 0 bytes

                    | Initial total  | 214.96 kB |                60.12 kB

Lazy chunk files    | Names          |  Raw size | Estimated transfer size
chunk-5PV7XSBR.js   | test-component |  59.39 kB |                10.30 kB

Without the comment:

Initial chunk files | Names          |  Raw size | Estimated transfer size
chunk-NOK43ORO.js   | -              | 195.29 kB |                49.77 kB
main-EVKXTY5S.js    | main           |  78.18 kB |                19.88 kB
styles-5INURTSO.css | styles         |   0 bytes |                 0 bytes

                    | Initial total  | 273.47 kB |                69.65 kB

Lazy chunk files    | Names          |  Raw size | Estimated transfer size
chunk-IGEEQONQ.js   | test-component | 304 bytes |               304 bytes

If you happen to configure snack-bar, form-field, and dialog, you already reach a bundle size of 405kB, which is just shy of the 500kB warning for initial bundle size. If you add anything remotely big like a CSS theme, you're easily over that limit. Note that if you add a pre-built Material theme, it adds an extra 7kB.

I'm not sure about the internals of the library, but it seems rather odd. I feel like the injection tokens shouldn't cause the rest of the features to be loaded.

Reproduction

StackBlitz link: https://stackblitz.com/edit/ldgbpznx-ia2hbzsb?file=src%2Ftest.ts,src%2Fmain.ts

Expected Behavior

Load the actual components lazily.

Actual Behavior

The components are in the initial bundle.

Environment


     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 20.0.2
Node: 22.13.1
Package Manager: npm 9.6.4
OS: win32 x64

Angular: 20.0.3
... cdk, common, compiler, compiler-cli, core, forms, material
... platform-browser, router

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.2000.2
@angular-devkit/core         20.0.2
@angular-devkit/schematics   20.0.2
@angular/build               20.0.2
@angular/cli                 20.0.2
@schematics/angular          20.0.2
rxjs                         7.8.2
typescript                   5.8.3

Activity

crisbeto

crisbeto commented on Jun 18, 2025

@crisbeto
Member

This is likely a tooling issue since we don't have much control over how code is split.

alan-agius4

alan-agius4 commented on Jun 18, 2025

@alan-agius4
Contributor

From a tooling perspective this is working as expected. Both MatFormField and MAT_FORM_FIELD_DEFAULT_OPTIONS are exported from @angular/material/form-field. This results in the entire module being included in the main.js bundle.

See also: evanw/esbuild#3531

alan-agius4

alan-agius4 commented on Jun 18, 2025

@alan-agius4
Contributor

Something went wrong, whilst transferring the issue.
Duplicate of #31375

angular-automatic-lock-bot

angular-automatic-lock-bot commented on Jul 19, 2025

@angular-automatic-lock-bot

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

locked and limited conversation to collaborators on Jul 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @crisbeto@wartab@alan-agius4

        Issue actions

          Configuring default options for different mat components results in the entire component being in the initial bundle · Issue #31375 · angular/components