From ae684b158c78ed7671fd33dbf0e263f445b54876 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 7 May 2024 12:01:34 +0200 Subject: [PATCH] perf(material/core): speed up M3 compilation 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. --- src/material/core/tokens/_m3-tokens.scss | 41 ++++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/material/core/tokens/_m3-tokens.scss b/src/material/core/tokens/_m3-tokens.scss index f8aa47040666..b35fc624095d 100644 --- a/src/material/core/tokens/_m3-tokens.scss +++ b/src/material/core/tokens/_m3-tokens.scss @@ -57,6 +57,32 @@ ); } +$_cached-token-slots: null; + +/// Determines the token slots for all components. +@function _get-token-slots() { + // Cache the slots since they're constant and calculating + // them appears to be expensive (see #29009). + @if ($_cached-token-slots) { + @return $_cached-token-slots; + } + + // TODO(mmalerba): Refactor this to not depend on the legacy theme when moving out of + // material-experimental. This is a hack for now because there is no good way to get the token + // slots in material-experimental without exposing them all from material. + $fake-theme: m2-theming.define-light-theme(( + color: ( + primary: m2-theming.define-palette(m2-theming.$red-palette), + accent: m2-theming.define-palette(m2-theming.$red-palette), + warn: m2-theming.define-palette(m2-theming.$red-palette), + ), + typography: m2-theming.define-typography-config(), + density: 0 + )); + $_cached-token-slots: m2-tokens.m2-tokens-from-theme($fake-theme) !global; + @return $_cached-token-slots; +} + /// Generates a set of namespaced tokens for all components. /// @param {Map} $systems The MDC system tokens /// @param {Boolean} $include-non-systemized Whether to include non-systemized tokens @@ -75,20 +101,7 @@ // DO NOT REMOVE // This function is used internally. $systems: format-tokens.private-format-tokens($systems); - - // TODO(mmalerba): Refactor this to not depend on the legacy theme when moving out of - // material-experimental. This is a hack for now because there is no good way to get the token - // slots in material-experimental without exposing them all from material. - $fake-theme: m2-theming.define-light-theme(( - color: ( - primary: m2-theming.define-palette(m2-theming.$red-palette), - accent: m2-theming.define-palette(m2-theming.$red-palette), - warn: m2-theming.define-palette(m2-theming.$red-palette), - ), - typography: m2-theming.define-typography-config(), - density: 0 - )); - $token-slots: m2-tokens.m2-tokens-from-theme($fake-theme); + $token-slots: _get-token-slots(); // TODO(mmalerba): Fill in remaining tokens. $result: sass-utils.deep-merge-all(