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
This commit is contained in:
Robin Malfait 2023-07-05 16:19:03 +02:00 • committed by Jordan Pittman
parent 1c9bb387e1
commit 5b9cbb3a81
5 changed files with 18 additions and 14 deletions

View file

@ -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

View file

@ -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...')

View file

@ -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')

View file

@ -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) {

View file

@ -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)