From e3111fe23f3db09228cbd34cb5cd56892e0301f3 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 5 Jul 2023 16:19:03 +0200 Subject: [PATCH] Make PostCSS plugin async to improve performance (#11548) * make main plugin async This way we can improve the `fs.readFileSync` to a bunch of `fs.promises.readFile` in a `Promise.all` instead. * make CLI plugin async * update CHANGELOG --- CHANGELOG.md | 1 + src/cli/build/plugin.js | 4 ++-- src/lib/expandTailwindAtRules.js | 16 +++++++++------- src/plugin.js | 6 +++--- src/processTailwindFeatures.js | 5 +++-- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a45da30bdf62..8649c2df7fb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Escape animation names when prefixes contain special characters ([#11470](https://github.com/tailwindlabs/tailwindcss/pull/11470)) - Sort classes using position of first matching rule ([#11504](https://github.com/tailwindlabs/tailwindcss/pull/11504)) - Allow variant to be an at-rule without a prelude ([#11589](https://github.com/tailwindlabs/tailwindcss/pull/11589)) +- Make PostCSS plugin async to improve performance ([#11548](https://github.com/tailwindlabs/tailwindcss/pull/11548)) ### Added diff --git a/src/cli/build/plugin.js b/src/cli/build/plugin.js index 9f3f6f52ff27..6af590dc5efe 100644 --- a/src/cli/build/plugin.js +++ b/src/cli/build/plugin.js @@ -278,9 +278,9 @@ export async function createProcessor(args, cliConfigPath) { let tailwindPlugin = () => { return { postcssPlugin: 'tailwindcss', - Once(root, { result }) { + async Once(root, { result }) { env.DEBUG && console.time('Compiling CSS') - tailwind(({ createContext }) => { + await tailwind(({ createContext }) => { console.error() console.error('Rebuilding...') diff --git a/src/lib/expandTailwindAtRules.js b/src/lib/expandTailwindAtRules.js index bf7d8f17f8ed..835c1622f1ad 100644 --- a/src/lib/expandTailwindAtRules.js +++ b/src/lib/expandTailwindAtRules.js @@ -98,7 +98,7 @@ function buildStylesheet(rules, context) { } export default function expandTailwindAtRules(context) { - return (root) => { + return async (root) => { let layerNodes = { base: null, components: null, @@ -145,12 +145,14 @@ export default function expandTailwindAtRules(context) { // getClassCandidatesOxide(file, transformer(content), extractor, candidates, seen) // } } else { - for (let { file, content, extension } of context.changedContent) { - let transformer = getTransformer(context.tailwindConfig, extension) - let extractor = getExtractor(context, extension) - content = file ? fs.readFileSync(file, 'utf8') : content - getClassCandidates(transformer(content), extractor, candidates, seen) - } + await Promise.all( + context.changedContent.map(async ({ file, content, extension }) => { + let transformer = getTransformer(context.tailwindConfig, extension) + let extractor = getExtractor(context, extension) + content = file ? await fs.promises.readFile(file, 'utf8') : content + getClassCandidates(transformer(content), extractor, candidates, seen) + }) + ) } env.DEBUG && console.timeEnd('Reading changed files') diff --git a/src/plugin.js b/src/plugin.js index 59f5fab014c6..bbb8cc14dd37 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -13,7 +13,7 @@ module.exports = function tailwindcss(configOrPath) { console.time('JIT TOTAL') return root }, - function (root, result) { + async function (root, result) { // Use the path for the `@config` directive if it exists, otherwise use the // path for the file being processed configOrPath = findAtConfigPath(root, result) ?? configOrPath @@ -25,14 +25,14 @@ module.exports = function tailwindcss(configOrPath) { for (const root of roots) { if (root.type === 'root') { - processTailwindFeatures(context)(root, result) + await processTailwindFeatures(context)(root, result) } } return } - processTailwindFeatures(context)(root, result) + await processTailwindFeatures(context)(root, result) }, __OXIDE__ && function lightningCssPlugin(_root, result) { diff --git a/src/processTailwindFeatures.js b/src/processTailwindFeatures.js index 952e17a13762..fa363b003bf2 100644 --- a/src/processTailwindFeatures.js +++ b/src/processTailwindFeatures.js @@ -12,7 +12,7 @@ import { createContext } from './lib/setupContextUtils' import { issueFlagNotices } from './featureFlags' export default function processTailwindFeatures(setupContext) { - return function (root, result) { + return async function (root, result) { let { tailwindDirectives, applyDirectives } = normalizeTailwindDirectives(root) detectNesting()(root, result) @@ -44,7 +44,8 @@ export default function processTailwindFeatures(setupContext) { issueFlagNotices(context.tailwindConfig) - expandTailwindAtRules(context)(root, result) + await expandTailwindAtRules(context)(root, result) + // Partition apply rules that are generated by // addComponents, addUtilities and so on. partitionApplyAtRules()(root, result)