Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Significant Slowdown in M3 Runtime Compilation #28971

Open
1 task
flipcasa opened this issue Apr 26, 2024 · 5 comments
Open
1 task

Significant Slowdown in M3 Runtime Compilation #28971

flipcasa opened this issue Apr 26, 2024 · 5 comments
Labels
area: material/core M3 needs investigation A member of the team needs to do further investigation to determine the root cause P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@flipcasa
Copy link

flipcasa commented Apr 26, 2024

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

Building our NX monorepo, particularly when utilizing M3 material components at runtime, is experiencing noticeable delays. This slowdown in compilation time is impacting our development efficiency.

Without M3, the compilation process takes approximately 2 seconds. However, with M3 integrated, the compilation time extends to 40 seconds or more.

Reproduction

StackBlitz link:
Steps to reproduce:
1.
2.

Expected Behavior

.

Actual Behavior

.

Environment

  • Angular: v18.0.0-rc.0
  • CDK/Material: v18.0.0-rc.0
  • Browser(s): chrome
  • Operating System (e.g. Windows, macOS, Ubuntu): mac
@flipcasa flipcasa added the needs triage This issue needs to be triaged by the team label Apr 26, 2024
@crisbeto
Copy link
Member

crisbeto commented May 6, 2024

I believe that Nx uses some sort of build caching. Do you see these slowdowns consistently or only on the initial build? Also what changes did you make to enable M3? We export all the APIs through the same _index.scss so I would expect the build graph to look identical no matter what version of Material you're using.

@amysorto amysorto added needs: clarification The issue does not contain enough information for the team to determine if it is a real bug and removed needs triage This issue needs to be triaged by the team labels May 6, 2024
@flipcasa
Copy link
Author

flipcasa commented May 6, 2024

@crisbeto
slowdown is consistent

@use '@angular/material' as mat;
@use 'sass:map';

mat.$theme-legacy-inspection-api-compatibility: false;

// Create a theme with the specified color type and density.
@function create-theme($type: light, $density: 0, $primary: mat.$blue-palette, $tertiary: mat.$violet-palette) {
  @return mat.define-theme(
    (
      color: (
        theme-type: $type,
        primary: $primary,
        tertiary: $tertiary
      ),
      density: (
        scale: $density
      ),
      typography: (
        brand-family: 'Be Vietnam Pro',
        plain-family: 'sans-serif',
        // regular-weight: 400,
        // medium-weight: 500,
        // bold-weight: 700
      )
    )
  );
}

// Define the default (light) theme.
$light-theme: create-theme(
  $type: light
);

// Create our dark theme.
$dark-theme: create-theme(
  $type: dark
);

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat.core();

// Include the default theme styles.
html {
  @include mat.all-component-themes($light-theme);
}
@include mat.typography-hierarchy($light-theme);

.dark-theme {
  // Include the dark theme color styles.
  @include mat.all-component-colors($dark-theme);
}

// Create classes for all density scales which are supported by all MDC-based components.
// The classes are applied conditionally based on the selected density in the dev-app layout
// component.
$density-scales: (0, -1, -2, -3, -4);
@each $scale in $density-scales {
  .density-#{$scale} {
    $density-theme: create-theme(
      $density: $scale
    );
    @include mat.all-component-densities($density-theme);
  }
}

.default {
  $light-theme: create-theme(
    $type: light,
    $primary: mat.$azure-palette,
    $tertiary: mat.$blue-palette
  );

  // Create our dark theme.
  $dark-theme: create-theme(
    $type: dark,
    $primary: mat.$azure-palette,
    $tertiary: mat.$blue-palette
  );

  // Theme Config
  @include mat.all-component-colors($light-theme);

  &.dark-theme {
    @include mat.all-component-colors($dark-theme);
  }

  // Enable backwards-compatibility CSS for color="..." API & typography hierarchy.
  &.back-compat {
    @include mat.color-variants-backwards-compatibility($light-theme);
    @include mat.typography-hierarchy($light-theme, $back-compat: true);

    &.dark-theme {
      @include mat.color-variants-backwards-compatibility($dark-theme);
    }
  }
}

Nx 18, 19
Angular 18 rc 0 even with experimental 17 package

before m3 and after m3 build times and runtimes doubled up

@crisbeto crisbeto added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent needs investigation A member of the team needs to do further investigation to determine the root cause area: material/core M3 and removed needs: clarification The issue does not contain enough information for the team to determine if it is a real bug labels May 7, 2024
@crisbeto
Copy link
Member

crisbeto commented May 7, 2024

Can you also post what your theme looked like for M2?

crisbeto added a commit to crisbeto/material2 that referenced this issue May 7, 2024
Mitigates a compile time regression when generating M3 themes. These changes reduce the compilation time in half by caching the dummy theme instead of recreating it for each invocation. We can get away with this since the dummy theme is constant.

Although these changes are a significant improvement, there's more room for improvement. Timings for reference:

At head:
```
M2 benchmark - 35s
M3 benchmark - 90s
Theme from angular#28971 - 19s
```

After these changes changes:
```
M2 benchmark - 36s
M3 benchmark - 56s
Theme from angular#28971 - 10s
```

Relates to angular#28971.
crisbeto added a commit to crisbeto/material2 that referenced this issue May 7, 2024
Mitigates a compile time regression when generating M3 themes. These changes reduce the compilation time in half by caching the dummy theme instead of recreating it for each invocation. We can get away with this since the dummy theme is constant.

Although these changes are a significant improvement, there's more room for improvement. Timings for reference:

At head:
```
M2 benchmark - 35s
M3 benchmark - 90s
Theme from angular#28971 - 19s
```

After these changes changes:
```
M2 benchmark - 36s
M3 benchmark - 56s
Theme from angular#28971 - 10s
```

Relates to angular#28971.
@crisbeto
Copy link
Member

crisbeto commented May 7, 2024

I've sent out #29009 which seems to cut the compilation time at least in half for M3.

crisbeto added a commit that referenced this issue May 7, 2024
Mitigates a compile time regression when generating M3 themes. These changes reduce the compilation time in half by caching the dummy theme instead of recreating it for each invocation. We can get away with this since the dummy theme is constant.

Although these changes are a significant improvement, there's more room for improvement. Timings for reference:

At head:
```
M2 benchmark - 35s
M3 benchmark - 90s
Theme from #28971 - 19s
```

After these changes changes:
```
M2 benchmark - 36s
M3 benchmark - 56s
Theme from #28971 - 10s
```

Relates to #28971.
crisbeto added a commit that referenced this issue May 7, 2024
Mitigates a compile time regression when generating M3 themes. These changes reduce the compilation time in half by caching the dummy theme instead of recreating it for each invocation. We can get away with this since the dummy theme is constant.

Although these changes are a significant improvement, there's more room for improvement. Timings for reference:

At head:
```
M2 benchmark - 35s
M3 benchmark - 90s
Theme from #28971 - 19s
```

After these changes changes:
```
M2 benchmark - 36s
M3 benchmark - 56s
Theme from #28971 - 10s
```

Relates to #28971.

(cherry picked from commit 0188516)
@flipcasa
Copy link
Author

flipcasa commented May 7, 2024

Can you also post what your theme looked like for M2?

Im adding my entire m3 and m2 styles @crisbeto

M3

@use '@angular/material' as mat;
@use 'sass:map';

mat.$theme-legacy-inspection-api-compatibility: false;

// Create a theme with the specified color type and density.
@function create-theme($type: light, $density: 0, $primary: mat.$blue-palette, $tertiary: mat.$violet-palette) {
  @return mat.define-theme(
    (
      color: (
        theme-type: $type,
        primary: $primary,
        tertiary: $tertiary
      ),
      density: (
        scale: $density
      ),
      typography: (
        brand-family: 'Be Vietnam Pro',
        plain-family: 'sans-serif',
        // regular-weight: 400,
        // medium-weight: 500,
        // bold-weight: 700
      )
    )
  );
}

// Define the default (light) theme.
$light-theme: create-theme(
  $type: light
);

// Create our dark theme.
$dark-theme: create-theme(
  $type: dark
);

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// **Be sure that you only ever include this mixin once!**
@include mat.core();

// Include the default theme styles.
html {
  @include mat.all-component-themes($light-theme);
}
@include mat.typography-hierarchy($light-theme);

.dark-theme {
  // Include the dark theme color styles.
  @include mat.all-component-colors($dark-theme);
}

// Create classes for all density scales which are supported by all MDC-based components.
// The classes are applied conditionally based on the selected density in the dev-app layout
// component.
$density-scales: (0, -1, -2, -3, -4);
@each $scale in $density-scales {
  .density-#{$scale} {
    $density-theme: create-theme(
      $density: $scale
    );
    @include mat.all-component-densities($density-theme);
  }
}

.theme-default {
  $light-theme: create-theme(
    $type: light,
    $primary: mat.$azure-palette,
    $tertiary: mat.$blue-palette
  );

  // Create our dark theme.
  $dark-theme: create-theme(
    $type: dark,
    $primary: mat.$azure-palette,
    $tertiary: mat.$blue-palette
  );

  // Theme Config
  @include mat.all-component-colors($light-theme);

  &.dark-theme {
    @include mat.all-component-colors($dark-theme);
  }

  // Enable backwards-compatibility CSS for color="..." API & typography hierarchy.
  &.back-compat {
    @include mat.color-variants-backwards-compatibility($light-theme);
    @include mat.typography-hierarchy($light-theme, $back-compat: true);

    &.dark-theme {
      @include mat.color-variants-backwards-compatibility($dark-theme);
    }
  }
}

.theme-rose {
  // Define the default (light) theme.
  $light-theme: create-theme(
    $type: light,
    $primary: mat.$rose-palette,
    $tertiary: mat.$red-palette
  );

  // Create our dark theme.
  $dark-theme: create-theme(
    $type: dark,
    $primary: mat.$rose-palette,
    $tertiary: mat.$red-palette
  );

  // Theme Config
  @include mat.all-component-colors($light-theme);

  &.dark-theme {
    @include mat.all-component-colors($dark-theme);
  }

  // Enable backwards-compatibility CSS for color="..." API & typography hierarchy.
  &.back-compat {
    @include mat.color-variants-backwards-compatibility($light-theme);
    @include mat.typography-hierarchy($light-theme, $back-compat: true);

    &.dark-theme {
      @include mat.color-variants-backwards-compatibility($dark-theme);
    }
  }
}

.theme-cyan {
  // Define the default (light) theme.
  $light-theme: create-theme(
    $type: light,
    $primary: mat.$cyan-palette,
    $tertiary: mat.$orange-palette
  );

  // Create our dark theme.
  $dark-theme: create-theme(
    $type: dark,
    $primary: mat.$cyan-palette,
    $tertiary: mat.$orange-palette
  );

  // Theme Config
  @include mat.all-component-colors($light-theme);

  &.dark-theme {
    @include mat.all-component-colors($dark-theme);
  }

  // Enable backwards-compatibility CSS for color="..." API & typography hierarchy.
  &.back-compat {
    @include mat.color-variants-backwards-compatibility($light-theme);
    @include mat.typography-hierarchy($light-theme, $back-compat: true);

    &.dark-theme {
      @include mat.color-variants-backwards-compatibility($dark-theme);
    }
  }
}

.theme-magenta {
  // Define the default (light) theme.
  $light-theme: create-theme(
    $type: light,
    $primary: mat.$magenta-palette,
    $tertiary: mat.$violet-palette
  );

  // Create our dark theme.
  $dark-theme: create-theme(
    $type: dark,
    $primary: mat.$magenta-palette,
    $tertiary: mat.$violet-palette
  );

  // Theme Config
  @include mat.all-component-colors($light-theme);

  &.dark-theme {
    @include mat.all-component-colors($dark-theme);
  }

  // Enable backwards-compatibility CSS for color="..." API & typography hierarchy.
  &.back-compat {
    @include mat.color-variants-backwards-compatibility($light-theme);
    @include mat.typography-hierarchy($light-theme, $back-compat: true);

    &.dark-theme {
      @include mat.color-variants-backwards-compatibility($dark-theme);
    }
  }
}

M2

@use '@angular/material' as mat;

mat.$theme-ignore-duplication-warnings: true;

// Light Theme Text
$dark-text: #000000;
$dark-primary-text: rgba($dark-text, 0.87);
$dark-accent-text: rgba($dark-primary-text, 0.54);

// Dark Theme text
$light-text: #ffffff;
$light-primary-text: $light-text;
$light-accent-text: rgba($light-primary-text, 0.7);

@include mat.core();

.theme-core {
  // Compute font config
  // @include mat.core($fontConfig);
  $mat-primary: (
    main: #115df6,
    lighter: #f0f5fe,
    darker: #0a41f2,
    200: #115df6,
    // For slide toggle,
    contrast:
      (
        main: $light-primary-text,
        lighter: $dark-primary-text,
        darker: $light-primary-text
      )
  );
  $theme-primary: mat.define-palette($mat-primary, main, lighter, darker);
  $mat-accent: (
    main: #042a76,
    lighter: #dbe7fe,
    darker: #021959,
    200: #042a76,
    // For slide toggle,
    contrast:
      (
        main: $light-primary-text,
        lighter: $dark-primary-text,
        darker: $light-primary-text
      )
  );
  $theme-accent: mat.define-palette($mat-accent, main, lighter, darker);
  $mat-warn: (
    main: #d17823,
    lighter: #f8dbd8,
    darker: #c05b15,
    200: #d17823,
    // For slide toggle,
    contrast:
      (
        main: $dark-primary-text,
        lighter: $dark-primary-text,
        darker: $light-primary-text
      )
  );
  $theme-warn: mat.define-palette($mat-warn, main, lighter, darker);

  --primary-color: #115df6;
  --primary-lighter-color: #f0f5fe;
  --primary-darker-color: #0a41f2;
  --text-primary-color: #{$light-primary-text};
  --text-primary-lighter-color: #{$dark-primary-text};
  --text-primary-darker-color: #{$light-primary-text};

  --accent-color: #042a76;
  --accent-lighter-color: #dbe7fe;
  --accent-darker-color: #021959;
  // --text-accent-color: #{$light-accent-text};
  // --text-accent-lighter-color: #{$dark-accent-text};
  // --text-accent-darker-color: #{$light-accent-text};

  --warn-color: #d17823;
  --warn-lighter-color: #f8dbd8;
  --warn-darker-color: #c05b15;
  --text-warn-color: #{$dark-primary-text};
  --text-warn-lighter-color: #{$dark-primary-text};
  --text-warn-darker-color: #{$light-primary-text};

  // Theme Config
  $typography: mat.define-typography-config(
    $font-family: 'Be Vietnam Pro',
    $headline-1: mat.define-typography-level(112px, 112px, 300, $letter-spacing: -0.0134em),
    $headline-2: mat.define-typography-level(56px, 56px, 400, $letter-spacing: -0.0089em),
    $headline-3: mat.define-typography-level(45px, 48px, 400, $letter-spacing: 0em),
    $headline-4: mat.define-typography-level(34px, 40px, 400, $letter-spacing: 0.0074em),
    $headline-5: mat.define-typography-level(24px, 32px, 400, $letter-spacing: 0em),
    $headline-6: mat.define-typography-level(20px, 32px, 500, $letter-spacing: 0.0075em),
    $subtitle-1: mat.define-typography-level(16px, 28px, 400, $letter-spacing: 0.0094em),
    $subtitle-2: mat.define-typography-level(15px, 24px, 500, $letter-spacing: 0.0067em),
    $body-2: mat.define-typography-level(14px, 24px, 500, $letter-spacing: 0.0179em),
    $body-1: mat.define-typography-level(14px, 20px, 400, $letter-spacing: 0.0179em),
    $button: mat.define-typography-level(14px, 14px, 500, $letter-spacing: 0.0893em),
    $caption: mat.define-typography-level(12px, 20px, 400, $letter-spacing: 0.0333em)
  );

  $theme: mat.define-light-theme(
    (
      color: (
        primary: $theme-primary,
        accent: $theme-accent,
        warn: $theme-warn
      ),
      typography: $typography,
      density: 0
    )
  );
  $altTheme: mat.define-dark-theme(
    (
      color: (
        primary: $theme-primary,
        accent: $theme-accent,
        warn: $theme-warn
      ),
      typography: $typography,
      density: 0
    )
  );

  @include mat.all-component-themes($theme);

  &.dark-theme {
    @include mat.all-component-colors($altTheme);
  }
}

.theme-dev {
  // Compute font config
  // @include mat.core($fontConfig);
  $mat-primary: (
    main: #b71c1c,
    lighter: #e9bbbb,
    darker: #9f1111,
    200: #b71c1c,
    // For slide toggle,
    contrast:
      (
        main: $light-primary-text,
        lighter: $dark-primary-text,
        darker: $light-primary-text
      )
  );
  $theme-primary: mat.define-palette($mat-primary, main, lighter, darker);
  $mat-accent: (
    main: #797979,
    lighter: #d7d7d7,
    darker: #5c5c5c,
    200: #797979,
    // For slide toggle,
    contrast:
      (
        main: $light-primary-text,
        lighter: $dark-primary-text,
        darker: $light-primary-text
      )
  );
  $theme-accent: mat.define-palette($mat-accent, main, lighter, darker);
  $mat-warn: (
    main: #ff0000,
    lighter: #ffb3b3,
    darker: #ff0000,
    200: #ff0000,
    // For slide toggle,
    contrast:
      (
        main: $dark-primary-text,
        lighter: $dark-primary-text,
        darker: $light-primary-text
      )
  );
  $theme-warn: mat.define-palette($mat-warn, main, lighter, darker);

  --primary-color: #b71c1c;
  --primary-lighter-color: #e9bbbb;
  --primary-darker-color: #9f1111;
  --text-primary-color: #{$light-primary-text};
  --text-primary-lighter-color: #{$dark-primary-text};
  --text-primary-darker-color: #{$light-primary-text};

  --accent-color: #797979;
  --accent-lighter-color: #d7d7d7;
  --accent-darker-color: #5c5c5c;
  // --text-accent-color: #{$light-accent-text};
  // --text-accent-lighter-color: #{$dark-accent-text};
  // --text-accent-darker-color: #{$light-accent-text};

  --warn-color: #ff0000;
  --warn-lighter-color: #ffb3b3;
  --warn-darker-color: #ff0000;
  --text-warn-color: #{$light-primary-text};
  --text-warn-lighter-color: #{$dark-primary-text};
  --text-warn-darker-color: #{$light-primary-text};

  // Theme Config
  $typography: mat.define-typography-config(
    $font-family: 'Be Vietnam Pro',
    $headline-1: mat.define-typography-level(112px, 112px, 300, $letter-spacing: -0.0134em),
    $headline-2: mat.define-typography-level(56px, 56px, 400, $letter-spacing: -0.0089em),
    $headline-3: mat.define-typography-level(45px, 48px, 400, $letter-spacing: 0em),
    $headline-4: mat.define-typography-level(34px, 40px, 400, $letter-spacing: 0.0074em),
    $headline-5: mat.define-typography-level(24px, 32px, 400, $letter-spacing: 0em),
    $headline-6: mat.define-typography-level(20px, 32px, 500, $letter-spacing: 0.0075em),
    $subtitle-1: mat.define-typography-level(16px, 28px, 400, $letter-spacing: 0.0094em),
    $subtitle-2: mat.define-typography-level(15px, 24px, 500, $letter-spacing: 0.0067em),
    $body-2: mat.define-typography-level(14px, 24px, 500, $letter-spacing: 0.0179em),
    $body-1: mat.define-typography-level(14px, 20px, 400, $letter-spacing: 0.0179em),
    $button: mat.define-typography-level(14px, 14px, 500, $letter-spacing: 0.0893em),
    $caption: mat.define-typography-level(12px, 20px, 400, $letter-spacing: 0.0333em)
  );

  $theme: mat.define-light-theme(
    (
      color: (
        primary: $theme-primary,
        accent: $theme-accent,
        warn: $theme-warn
      ),
      typography: $typography,
      density: 0
    )
  );
  $altTheme: mat.define-dark-theme(
    (
      color: (
        primary: $theme-primary,
        accent: $theme-accent,
        warn: $theme-warn
      ),
      typography: $typography,
      density: 0
    )
  );

  @include mat.all-component-themes($theme);

  &.dark-theme {
    @include mat.all-component-colors($altTheme);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: material/core M3 needs investigation A member of the team needs to do further investigation to determine the root cause P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
Development

No branches or pull requests

3 participants