From 49fe74e241d75456c65a7cd439b9eb8842e9d6d7 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 18 Oct 2023 09:55:19 +0000 Subject: [PATCH] perf(@angular-devkit/build-angular): reduce CLI loading times by removing critters from critical path Critters has a number of large deps like postcss which slow down the Angular CLI loading times. (cherry picked from commit 57fef7b8d32d89dbb49fa1a2fc6d56a5bf4b2943) --- .../src/builders/app-shell/index.ts | 18 +++++++++++------- .../src/builders/prerender/render-worker.ts | 5 ++++- .../src/tools/esbuild/index-html-generator.ts | 3 ++- .../utils/index-file/inline-critical-css.ts | 3 +-- .../src/utils/server-rendering/render-page.ts | 5 ++++- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts b/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts index 208c3d5c611d..dc3794d3d41d 100644 --- a/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts @@ -18,7 +18,7 @@ import * as path from 'path'; import Piscina from 'piscina'; import { normalizeOptimization } from '../../utils'; import { assertIsError } from '../../utils/error'; -import { InlineCriticalCssProcessor } from '../../utils/index-file/inline-critical-css'; +import type { InlineCriticalCssProcessor } from '../../utils/index-file/inline-critical-css'; import { augmentAppWithServiceWorker } from '../../utils/service-worker'; import { Spinner } from '../../utils/spinner'; import { BrowserBuilderOutput } from '../browser'; @@ -56,12 +56,16 @@ async function _renderUniversal( const projectRoot = path.join(root, (projectMetadata.root as string | undefined) ?? ''); const { styles } = normalizeOptimization(browserOptions.optimization); - const inlineCriticalCssProcessor = styles.inlineCritical - ? new InlineCriticalCssProcessor({ - minify: styles.minify, - deployUrl: browserOptions.deployUrl, - }) - : undefined; + let inlineCriticalCssProcessor: InlineCriticalCssProcessor | undefined; + if (styles.inlineCritical) { + const { InlineCriticalCssProcessor } = await import( + '../../utils/index-file/inline-critical-css' + ); + inlineCriticalCssProcessor = new InlineCriticalCssProcessor({ + minify: styles.minify, + deployUrl: browserOptions.deployUrl, + }); + } const renderWorker = new Piscina({ filename: require.resolve('./render-worker'), diff --git a/packages/angular_devkit/build_angular/src/builders/prerender/render-worker.ts b/packages/angular_devkit/build_angular/src/builders/prerender/render-worker.ts index c9b0c9bf7343..9806c1c112c3 100644 --- a/packages/angular_devkit/build_angular/src/builders/prerender/render-worker.ts +++ b/packages/angular_devkit/build_angular/src/builders/prerender/render-worker.ts @@ -12,7 +12,6 @@ import assert from 'node:assert'; import * as fs from 'node:fs'; import * as path from 'node:path'; import { workerData } from 'node:worker_threads'; -import { InlineCriticalCssProcessor } from '../../utils/index-file/inline-critical-css'; export interface RenderOptions { indexFile: string; @@ -122,6 +121,10 @@ async function render({ } if (inlineCriticalCss) { + const { InlineCriticalCssProcessor } = await import( + '../../utils/index-file/inline-critical-css' + ); + const inlineCriticalCssProcessor = new InlineCriticalCssProcessor({ deployUrl: deployUrl, minify: minifyCss, diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts index b353827ab937..d4553481d944 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts @@ -10,7 +10,6 @@ import assert from 'node:assert'; import path from 'node:path'; import { NormalizedApplicationBuildOptions } from '../../builders/application/options'; import { IndexHtmlGenerator } from '../../utils/index-file/index-html-generator'; -import { InlineCriticalCssProcessor } from '../../utils/index-file/inline-critical-css'; import { BuildOutputFile, BuildOutputFileType, InitialFileRecord } from './bundler-context'; export async function generateIndexHtml( @@ -107,6 +106,8 @@ export async function generateIndexHtml( }; } + const { InlineCriticalCssProcessor } = await import('../../utils/index-file/inline-critical-css'); + const inlineCriticalCssProcessor = new InlineCriticalCssProcessor({ minify: false, // CSS has already been minified during the build. readAsset, diff --git a/packages/angular_devkit/build_angular/src/utils/index-file/inline-critical-css.ts b/packages/angular_devkit/build_angular/src/utils/index-file/inline-critical-css.ts index f10aaf2cd1e2..862151b0cbd0 100644 --- a/packages/angular_devkit/build_angular/src/utils/index-file/inline-critical-css.ts +++ b/packages/angular_devkit/build_angular/src/utils/index-file/inline-critical-css.ts @@ -6,10 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ +import Critters from 'critters'; import { readFile } from 'node:fs/promises'; -const Critters: typeof import('critters').default = require('critters'); - /** * Pattern used to extract the media query set by Critters in an `onload` handler. */ diff --git a/packages/angular_devkit/build_angular/src/utils/server-rendering/render-page.ts b/packages/angular_devkit/build_angular/src/utils/server-rendering/render-page.ts index 58bc6c676c91..67510b2d7db5 100644 --- a/packages/angular_devkit/build_angular/src/utils/server-rendering/render-page.ts +++ b/packages/angular_devkit/build_angular/src/utils/server-rendering/render-page.ts @@ -8,7 +8,6 @@ import type { ApplicationRef, StaticProvider } from '@angular/core'; import { basename } from 'node:path'; -import { InlineCriticalCssProcessor } from '../index-file/inline-critical-css'; import { loadEsmModule } from '../load-esm'; import { MainServerBundleExports } from './main-bundle-exports'; @@ -94,6 +93,10 @@ export async function renderPage({ } if (inlineCriticalCss) { + const { InlineCriticalCssProcessor } = await import( + '../../utils/index-file/inline-critical-css' + ); + const inlineCriticalCssProcessor = new InlineCriticalCssProcessor({ minify: false, // CSS has already been minified during the build. readAsset: async (filePath) => {