From 72a7bc0d225d75560c30f295e0a2a0b5ff5802d9 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 21 May 2021 13:33:22 +0200 Subject: [PATCH] perf(@angular-devkit/build-angular): disable CSS optimization parallelism for components styles Since we rely on child compilations to compile components CSS, using the `parallel` option will cause a significant overhead because each compilation will need to spawn a worker, in this mode the worker limit is not be honored because `css-minimizer-webpack-plugin` spawn and calulators workers during the optimization phase of a compilation and not globally per instance hence causes OOM because a large number of workers to be spawned simultaneously. Closes #20883 (cherry picked from commit 1ab2ef9a3f3d416241db9f34e285da265d9cc27f) --- .../src/webpack/configs/common.ts | 24 ---------- .../src/webpack/configs/styles.ts | 44 +++++++++++++++++++ 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/webpack/configs/common.ts b/packages/angular_devkit/build_angular/src/webpack/configs/common.ts index 851f566192b2..774e5c50b45b 100644 --- a/packages/angular_devkit/build_angular/src/webpack/configs/common.ts +++ b/packages/angular_devkit/build_angular/src/webpack/configs/common.ts @@ -313,30 +313,6 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration { } const extraMinimizers = []; - if (stylesOptimization.minify) { - const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); - extraMinimizers.push( - new CssMinimizerPlugin({ - // component styles retain their original file name - test: /\.(?:css|scss|sass|less|styl)$/, - parallel: maxWorkers, - minify: [CssMinimizerPlugin.cssnanoMinify], - minimizerOptions: { - preset: [ - 'default', - { - // Disable SVG optimizations, as this can cause optimizations which are not compatible in all browsers. - svgo: false, - // Disable `calc` optimizations, due to several issues. #16910, #16875, #17890 - calc: false, - // Disable CSS rules sorted due to several issues #20693, https://github.com/ionic-team/ionic-framework/issues/23266 and https://github.com/cssnano/cssnano/issues/1054 - cssDeclarationSorter: false, - }, - ], - }, - }), - ); - } if (scriptsOptimization) { const TerserPlugin = require('terser-webpack-plugin'); diff --git a/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts b/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts index 918bb5f1eb82..7fd4acb089db 100644 --- a/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts +++ b/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts @@ -13,6 +13,7 @@ import { ExtraEntryPoint } from '../../browser/schema'; import { SassWorkerImplementation } from '../../sass/sass-service'; import { BuildBrowserFeatures } from '../../utils/build-browser-features'; import { WebpackConfigOptions } from '../../utils/build-options'; +import { maxWorkers } from '../../utils/environment-options'; import { AnyComponentStyleBudgetChecker, PostcssCliResources, @@ -402,11 +403,54 @@ export function getStylesConfig(wco: WebpackConfigOptions): webpack.Configuratio }); } + const extraMinimizers = []; + if (buildOptions.optimization.styles.minify) { + const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); + const minimizerOptions = { + preset: [ + 'default', + { + // Disable SVG optimizations, as this can cause optimizations which are not compatible in all browsers. + svgo: false, + // Disable `calc` optimizations, due to several issues. #16910, #16875, #17890 + calc: false, + // Disable CSS rules sorted due to several issues #20693, https://github.com/ionic-team/ionic-framework/issues/23266 and https://github.com/cssnano/cssnano/issues/1054 + cssDeclarationSorter: false, + }, + ], + }; + + const globalBundlesRegExp = new RegExp( + `^(${Object.keys(entryPoints).join('|')})(\.[0-9a-f]{20})?.css$`, + ); + + extraMinimizers.push( + new CssMinimizerPlugin({ + // Component styles retain their original file name + test: /\.(?:css|scss|sass|less|styl)$/, + parallel: false, + exclude: globalBundlesRegExp, + minify: [CssMinimizerPlugin.cssnanoMinify], + minimizerOptions, + }), + new CssMinimizerPlugin({ + test: /\.css$/, + include: globalBundlesRegExp, + parallel: maxWorkers, + minify: [CssMinimizerPlugin.cssnanoMinify], + minimizerOptions, + }), + ); + } + return { entry: entryPoints, module: { rules: [...fileLanguageRules, ...inlineLanguageRules], }, + optimization: { + minimizer: extraMinimizers, + }, plugins: extraPlugins, }; }