Disable colormin feature from cssnano#53393
Conversation
cssnano by default tries to convert `rgb` colors to an `hsla` color when
the `hsla` color is shorter for minification purposes.
The issue with this is that the colors aren't the same and we are losing
data when converting to `hsla`.
Input:
```css
html {
background-color: rgb(143 101 98 / 43%);
}
```
Output:
```css
html {
background-color: hsla(4, 19%, 47%, .43);
}
```
(I pretty printed it to make the diff a bit nicer).
If we would convert this `hsla` color back to `rgb` syntax, then it
results in:
```css
html {
background-color: rgb(143 100 97 / 43%);
}
```
Comparing the original value with the last value, then you can see the
difference:
```diff
html {
- background-color: rgb(143 101 98 / 43%);
+ background-color: rgb(143 100 97 / 43%);
/* ^ ^ */
}
```
To solve this issue, we can just disable the `colormin` minification of
`cssnano` entirely.
2353605 to
9124f0f
Compare
Took example code from another existing test: `test/e2e/app-dir/app-css/index.test.css`
|
I've opened an issue on cssnano as well in case they'd like to make some changes around this upstream, but since they are looking for new maintainers on that package it might be something anyone can easily prioritize right now and might not happen very quickly: |
Tests Passed |
Stats from current PRDefault Build (Increase detected
|
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| buildDuration | 19.3s | 16.3s | N/A |
| buildDurationCached | 15.4s | 13.5s | N/A |
| nodeModulesSize | 418 MB | 418 MB | |
| nextStartRea..uration (ms) | 429ms | 427ms | N/A |
Client Bundles (main, webpack)
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| 5306-HASH.js gzip | 54 kB | 54 kB | N/A |
| 8276.HASH.js gzip | 169 B | 168 B | N/A |
| 8377-HASH.js gzip | 5.44 kB | 5.44 kB | N/A |
| bccd1874-HASH.js gzip | 52.9 kB | 52.9 kB | ✓ |
| framework-HASH.js gzip | 57.5 kB | 57.5 kB | N/A |
| main-app-HASH.js gzip | 240 B | 242 B | N/A |
| main-HASH.js gzip | 34.4 kB | 34.4 kB | N/A |
| webpack-HASH.js gzip | 1.71 kB | 1.71 kB | N/A |
| Overall change | 52.9 kB | 52.9 kB | ✓ |
Legacy Client Bundles (polyfills)
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| polyfills-HASH.js gzip | 39.4 kB | 39.4 kB | ✓ |
| Overall change | 39.4 kB | 39.4 kB | ✓ |
Client Pages
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| _app-HASH.js gzip | 193 B | 193 B | ✓ |
| _error-HASH.js gzip | 193 B | 193 B | ✓ |
| amp-HASH.js gzip | 512 B | 510 B | N/A |
| css-HASH.js gzip | 343 B | 342 B | N/A |
| dynamic-HASH.js gzip | 1.84 kB | 1.84 kB | ✓ |
| edge-ssr-HASH.js gzip | 265 B | 265 B | ✓ |
| head-HASH.js gzip | 363 B | 362 B | N/A |
| hooks-HASH.js gzip | 393 B | 392 B | N/A |
| image-HASH.js gzip | 4.57 kB | 4.57 kB | N/A |
| index-HASH.js gzip | 268 B | 268 B | ✓ |
| link-HASH.js gzip | 2.35 kB | 2.34 kB | N/A |
| routerDirect..HASH.js gzip | 328 B | 328 B | ✓ |
| script-HASH.js gzip | 397 B | 397 B | ✓ |
| withRouter-HASH.js gzip | 323 B | 326 B | N/A |
| 1afbb74e6ecf..834.css gzip | 106 B | 106 B | ✓ |
| Overall change | 3.59 kB | 3.59 kB | ✓ |
Client Build Manifests
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| _buildManifest.js gzip | 749 B | 747 B | N/A |
| Overall change | 0 B | 0 B | ✓ |
Rendered Page Sizes
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| index.html gzip | 524 B | 524 B | ✓ |
| link.html gzip | 538 B | 538 B | ✓ |
| withRouter.html gzip | 519 B | 521 B | N/A |
| Overall change | 1.06 kB | 1.06 kB | ✓ |
Edge SSR bundle Size
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| edge-ssr.js gzip | 129 kB | 129 kB | N/A |
| page.js gzip | 208 kB | 208 kB | N/A |
| Overall change | 0 B | 0 B | ✓ |
Middleware size
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| middleware-b..fest.js gzip | 670 B | 667 B | N/A |
| middleware-r..fest.js gzip | 155 B | 156 B | N/A |
| middleware.js gzip | 31.3 kB | 31.3 kB | N/A |
| edge-runtime..pack.js gzip | 844 B | 844 B | ✓ |
| Overall change | 844 B | 844 B | ✓ |
Next Runtimes
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| 274-experime...dev.js gzip | 322 B | 322 B | ✓ |
| 274.runtime.dev.js gzip | 314 B | 314 B | ✓ |
| app-page-exp...dev.js gzip | 374 kB | 374 kB | ✓ |
| app-page-exp..prod.js gzip | 130 kB | 130 kB | ✓ |
| app-page-tur..prod.js gzip | 143 kB | 143 kB | ✓ |
| app-page-tur..prod.js gzip | 139 kB | 139 kB | ✓ |
| app-page.run...dev.js gzip | 362 kB | 362 kB | ✓ |
| app-page.run..prod.js gzip | 126 kB | 126 kB | ✓ |
| app-route-ex...dev.js gzip | 37.6 kB | 37.6 kB | ✓ |
| app-route-ex..prod.js gzip | 25.6 kB | 25.6 kB | ✓ |
| app-route-tu..prod.js gzip | 25.6 kB | 25.6 kB | ✓ |
| app-route-tu..prod.js gzip | 25.4 kB | 25.4 kB | ✓ |
| app-route.ru...dev.js gzip | 39.2 kB | 39.2 kB | ✓ |
| app-route.ru..prod.js gzip | 25.4 kB | 25.4 kB | ✓ |
| pages-api-tu..prod.js gzip | 9.69 kB | 9.69 kB | ✓ |
| pages-api.ru...dev.js gzip | 11.6 kB | 11.6 kB | ✓ |
| pages-api.ru..prod.js gzip | 9.68 kB | 9.68 kB | ✓ |
| pages-turbo...prod.js gzip | 21.9 kB | 21.9 kB | ✓ |
| pages.runtim...dev.js gzip | 27.7 kB | 27.7 kB | ✓ |
| pages.runtim..prod.js gzip | 21.9 kB | 21.9 kB | ✓ |
| server.runti..prod.js gzip | 916 kB | 916 kB | ✓ |
| Overall change | 2.47 MB | 2.47 MB | ✓ |
build cache Overall increase ⚠️
| vercel/next.js canary | RobinMalfait/next.js fix/remove-colormin-from-cssnano | Change | |
|---|---|---|---|
| 0.pack gzip | 2.1 MB | 2.1 MB | N/A |
| index.pack gzip | 74.5 kB | 75.7 kB | |
| Overall change | 74.5 kB | 75.7 kB |
Diff details
Diff for main-HASH.js
Diff too large to display
2bb743b to
02b0d50
Compare
ztanner
left a comment
There was a problem hiding this comment.
Thank you for the PR! Apologies for the delay in getting to this
|
As per the latest discussion in the cssnano issue, would it make sense to change this to instead of disabling color minification entirely, we just disable the lossy HSLA conversions? They suggest the following fix: cssnano({
preset: ['default', { colormin: { hsl: false } }]
})Which my company has used in our Next.js config with great success. The file size reduction from still having non-lossy color compression is not significant I think in most use cases, but it seems like the better default than disabling it entirely for sites that do use a lot of colors. Happy to submit a PR if it would be helpful since our team has spent quite a bit of time head-scratching over why our colors looked wrong in production but not on local lol. |
cssnano by default tries to convert
rgbcolors to anhslacolor when thehslacolor is shorter for minification purposes.The issue with this is that the colors aren't the same and we are losing data when converting to
hsla.Input:
Output:
(I pretty printed it to make the diff a bit nicer).
If we would convert this
hslacolor back torgbsyntax, then it results in:Comparing the original value with the last value, then you can see the difference:
html { - background-color: rgb(143 101 98 / 43%); + background-color: rgb(143 100 97 / 43%); /* ^ ^ */ }To solve this issue, we can just disable the
colorminminification ofcssnanoentirely.