mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
This PR improves the `@tailwindcss/postcss` integration by using direct AST transformations between our own AST and PostCSS's AST. This allows us to skip a step where we convert our AST into a string, then parse it back into a PostCSS AST. The only downside is that we still have to print the AST into a string if we want to optimize the CSS using Lightning CSS. Luckily this only happens in production (`NODE_ENV=production`). This also introduces a new private `compileAst` API, that allows us to accept an AST as the input. This allows us to skip the PostCSS AST -> string -> parse into our own AST step. To summarize: Instead of: - Input: `PostCSS AST` -> `.toString()` -> `CSS.parse(…)` -> `Tailwind CSS AST` - Output: `Tailwind CSS AST` -> `toCSS(ast)` -> `postcss.parse(…)` -> `PostCSS AST` We will now do this instead: - Input: `PostCSS AST` -> `transform(…)` -> `Tailwind CSS AST` - Output: `Tailwind CSS AST` -> `transform(…)` -> `PostCSS AST` --- Running this on Catalyst, the time spent in the `@tailwindcss/postcss` looks like this: - Before: median time per run: 19.407687 ms - After: median time per run: 11.8796455 ms This is tested on Catalyst which roughly generates ~208kb worth of CSS in dev mode. While it's not a lot, skipping the stringification and parsing seems to improve this step by ~40%. Note: these times exclude scanning the actual candidates and only time the work needed for parsing/stringifying the CSS from and into ASTs. The actual numbers are a bit higher because of the Oxide scanner reading files from disk. But since that part is going to be there no matter what, it's not fair to include it in this benchmark. --------- Co-authored-by: Jordan Pittman <jordan@cryptica.me>