Angular从10升级到16后样式冗余问题的排查与解决
Angular 10升级到16后样式数量暴增问题
将Angular从10版本升级至16版本(同步升级Angular Material)后,发现控制台中使用的样式数量远多于10版本。16版本的body元素上存在大量CSS变量样式,例如:
--mat-paginator-container-text-font: Roboto, monospace; --mat-paginator-container-text-line-height: 20px; --mat-paginator-container-text-size: 12px; --mat-paginator-container-text-tracking: .0333333333em; --mat-paginator-container-text-weight: 400; --mat-paginator-select-trigger-text-size: 12px; --mdc-filled-text-field-label-text-font: Roboto, monospace; --mdc-filled-text-field-label-text-size: 16px;
当前使用的_material.variables.scss配置如下:
@include mat.core(); @include mat.all-component-typographies(); $my-primary: mat.define-palette(mat.$indigo-palette); $my-accent: mat.define-palette(mat.$teal-palette); $my-warn: mat.define-palette(mat.$red-palette); $my-theme: mat.define-light-theme(( color: ( primary: $my-primary, accent: $my-accent, warn: $my-warn, ), typography: mat.define-typography-config(), density: 0, )); $background: map-get($my-theme, background); $foreground: map-get($my-theme, foreground); /* stylelint-disable function-parentheses-space-inside */ $custom-typography: mat.define-typography-config( $font-family: 'Roboto, monospace', $headline-5: mat.define-typography-level(24px, 32px, 400), $body-2: mat.define-typography-level(14px, 20px, 400) ); /* stylelint-enable */ $config: mat.define-typography-config(); @include mat.all-component-themes($my-theme);
问题成因
- Angular Material底层架构变更:Angular 15+版本全面切换到基于MDC(Material Design Components for the Web)的底层实现,旧架构的Angular Material直接生成静态样式,而MDC会将组件的样式参数以CSS变量形式注入到根元素上,这是新架构的默认行为,用于支持更灵活的主题定制和动态样式切换。
- 冗余的Typography引入:当前配置中同时调用了
mat.all-component-typographies()和mat.all-component-themes(),但mat.all-component-themes()已经包含所有组件的主题(包括Typography样式),重复调用会导致Typography相关的CSS变量被重复注入。 - 自定义Typography未生效:定义了
$custom-typography但未传入mat.define-light-theme()的typography字段,导致默认Typography配置被应用,同时自定义配置未发挥作用,额外生成了不必要的样式变量。
解决方法
1. 移除冗余的Typography包含语句
删除配置中的@include mat.all-component-typographies();,避免重复注入Typography相关的CSS变量。
2. 应用自定义Typography到主题
将自定义的$custom-typography传入mat.define-light-theme()的typography属性,替换默认的空配置,确保只有自定义的Typography变量被生成:
$my-theme: mat.define-light-theme(( color: ( primary: $my-primary, accent: $my-accent, warn: $my-warn, ), typography: $custom-typography, // 替换为自定义配置 density: 0, ));
3. 删除未使用的冗余代码
移除无用的$config: mat.define-typography-config();语句,该变量未被任何代码引用。
优化后的完整配置
@include mat.core(); $my-primary: mat.define-palette(mat.$indigo-palette); $my-accent: mat.define-palette(mat.$teal-palette); $my-warn: mat.define-palette(mat.$red-palette); /* stylelint-disable function-parentheses-space-inside */ $custom-typography: mat.define-typography-config( $font-family: 'Roboto, monospace', $headline-5: mat.define-typography-level(24px, 32px, 400), $body-2: mat.define-typography-level(14px, 20px, 400) ); /* stylelint-enable */ $my-theme: mat.define-light-theme(( color: ( primary: $my-primary, accent: $my-accent, warn: $my-warn, ), typography: $custom-typography, density: 0, )); $background: map-get($my-theme, background); $foreground: map-get($my-theme, foreground); @include mat.all-component-themes($my-theme);
4. 可选:开启样式优化(Angular 16+)
如果仍觉得CSS变量过多,可以在angular.json中启用样式优化,自动移除未使用的CSS变量:
"projects": { "your-project-name": { "architect": { "build": { "options": { "optimization": { "styles": { "minify": true, "unused": true } } } } } } }
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

