question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Consider using lightningcss as a CSS minifier

See original GitHub issue

Describe the feature you’d like to request

Lightning CSS is a new CSS transformer and minifier in Rust, built by the team behind the Parcel bundler. It is significantly faster than any other CSS minifier I am aware of, while producing smaller output in many cases. It’s over 100x faster than cssnano, the CSS minifier used by Next.js today.

I think Next.js could adopt lightningcss as a minifier easily, and users would see reduced production build times, with potential for reduced bundle sizes as well. In the future, additional features such as replacing postcss-preset-env and autoprefixer could also be adopted, but minification is the easiest place to start.

The GitHub readme has information about the features. For more about the internal architecture, see the announcement blog post. As if March, it has been the default CSS minifier in Parcel.

Describe the solution you’d like

css-minimizer-webpack-plugin already supports usinglightningcss with a one line change.

new CssMinimizerPlugin({
  minify: CssMinimizerPlugin.lightningCssMinify,
  // ...
})

This could easily be opt-in at first (similar to the swcMinify option for JavaScript) if you are concerned about bugs or regressions.

Describe alternatives you’ve considered

I am biased as the main author of lightningcss, but I think changing the default would be a good choice. However, if you don’t want to do this, I think it would be nice to be able to customize the minifier more easily. I tried to write a Next.js plugin to do this, but it involves some brittle hackery to the webpack config. There’s no way to detect the default minimizer plugin, so you have to assume the index in the list of minimizers in the webpack config doesn’t change in order to delete the default and add the replacement. Perhaps a config option similar to the one supported by css-minimizer-webpack-plugin could be supported to allow users choice over the minifier they use.

I am aware that SWC is also working on a CSS minifier. However, lightningcss is ready today. Again, I’m biased, but I think the architecture of Lightning CSS will enable it to continue to be faster and produce smaller output. At least offering users a choice over what minifier they use would be better than locking them in.

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:15
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
devongovettcommented, Jul 9, 2022

Thus some optimization provided by @parcel/css might not be available (which might make the @parcel/css’s minification less effective).

True, but (a) it should be at least as good as cssnano, and (b) users can customize their browserslist so may be able to get additional benefit over the defaults.

So the adjacent atrules might not be common for others’ normal hand-written CSS, but the case does exist.

I just implemented it in https://github.com/parcel-bundler/parcel-css/commit/ae87b831412c9b6de9b216bc07ad4c8eda8700ac. Should go out with the next release.

However, the time saved by the @parcel/css might be counteracted by the elapsed time of the node native addon boot-up

Where does this concern come from? I just tested and on my machine:

require parcel css: 2.346ms
require cssnano: 15.728ms
4reactions
devongovettcommented, Jul 9, 2022

IIRC, parcel/css achieves a higher minify rate by applying “unsafe” minification (E.g., mangle top: 0; right: 0; bottom: 0; left: 0; into inset: 0;), which would not be available with Next.js’ default browserlist config.

No,@parcel/css does not do any unsafe transformations. However, you must specify the correct browser targets. inset is only output when the browser targets allow it. If you find a case where the output CSS behaves differently than the input in one of the target browsers, please report it as a bug.

FYI, React Beta Docs (https://beta.reactjs.org/) has only 1 CSS file and the after-minified size is at 75.2 KiB. Is it possible for @parcel/css to beat cssnano on this?

Browser targets have a big effect on this, since they allow @parcel/css to remove unnecessary prefixes, and use more compact syntax when supported.

  • cssnano – 75182 bytes
  • @parcel/css with browserslist: “chrome 61,edge 16,firefox 60,opera 48,safari 11” – 74363 bytes
  • @parcel/css with a more modern browserslist: “chrome 95” – 71564 bytes

Again, I wouldn’t expect the difference in size to be massive – cssnano is a very good minifier, and there’s only so much that can be done safely, especially in this case where the input CSS is generated by Tailwind rather than authored by hand. The ability to take advantage of browser improvements over time is a powerful feature though.

For instance, cssnano does support merging adjacent atrules (@media, @supports, etc.), but @parcel/css doesn’t

Merging adjacent @media/@supports rules with identical queries is a good feature request, though I’m not sure how often it would really occur in real-world code. Non-adjacent rules cannot be merged safely, as doing so could break specificity. Some minifiers will do this, and might look better on size benchmarks, but it’s not safe to do generally.

Also, IMHO a normal Next.js project would usually output less than 10 CSS files, thus the speed of parcel/css might not be a huge advantage here as well.

Depends how big those files are. The time can add up quickly, and can easily represent a significant percentage of the overall build time. Making this 100x faster could be a nice speedup.

however the @parcel/css has an install size of 3.05 MiB

This depends on the platform since @parcel/css is a binary, and binary sizes vary from platform to platform. But yes, binaries tend to be larger than source code. We’ve done some work to reduce the binary size as much as possible, but there are probably additional things we could look into if this is a big concern.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Lightning CSS
An extremely fast CSS parser, transformer, bundler, and minifier. ... Lightning CSS is written in Rust, a native systems programming language.
Read more >
Devon Govett on Twitter: "Excited to announce that Parcel ...
Excited to announce that Parcel CSS is now Lightning CSS! ⚡️ This new name makes it clear that it can be used outside...
Read more >
Any recommendations for a CSS minifier? - Stack Overflow
I think a style could be damaged easily by these minifiers if we use some css hacks inside css code. Backslashes and wierd...
Read more >
The Dev Times #59 - Transloadit
Lightning CSS. Lightning CSS is an extremely fast CSS parser, transformer, and minifier. Thanks to the power of Rust, you can expect speeds ......
Read more >
Web Weekly #79 | Stefan Judis Web Development
There's so much noise in the JavaScript ecosystem lately. ... Lightning CSS (formerly Parcel CSS) is a CSS transformer, bundler and minifier ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found