-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disable PostCSS-custom-properties in development #42829
Conversation
8be608e
to
4f6313d
Compare
Here is how your PR affects size of JS and CSS bundles shipped to the user's browser: Webpack Runtime (~31 bytes added 📈 [gzipped])
Webpack runtime for loading modules. It is included in the HTML page as an inline script. Is downloaded and parsed every time the app is loaded. Sections (~13 bytes removed 📉 [gzipped])
Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to. Async-loaded Components (~1714 bytes removed 📉 [gzipped])
React components that are loaded lazily, when a certain part of UI is displayed for the first time. Legend What is parsed and gzip size?Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory. Generated by performance advisor bot at iscalypsofastyet.com. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, does grepping all the CSS rules really take that long? I can't believe it 🙂
There are also other postcss.config.js
files in the repo that might benefit from a similar patch:
apps/notifications/postcss.config.js
packages/calypso-build/postcss.config.js
The config
module is probably not available in these, so we need to pass down the "want custom properties" flag in some other way. I remember @ockham did some improvements in these files in the last few months.
client/postcss.config.js
Outdated
const config = require( './server/config' ); | ||
const bundleEnv = config( 'env' ); | ||
|
||
if ( bundleEnv === 'development' ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can make this condition even more precise. We need postcss-custom-properties
only for browsers that don't support CSS variables, and that corresponds 1:1 with the fallback
build for IE11, doesn't it?
The evergreen
build can omit postcss-custom-properties
even in production.
And it can probably be also omitted from the desktop
build, after checking that the Electron that we currently use bundles a new enough Chrome. And that's virtually 100% certain, because CSS properties are a rather old feature at this moment.
@sgomes is the expert on our dual builds, might have some other suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of our evergreen browsers definitely support CSS custom properties, so you can certainly make use of that here. You'll need something like what we do in webpack.config.js
:
const isCalypsoClient = process.env.BROWSERSLIST_ENV !== 'server';
const isDesktop = calypsoEnv === 'desktop' || calypsoEnv === 'desktop-development';
const defaultBrowserslistEnv = isCalypsoClient && ! isDesktop ? 'evergreen' : 'defaults';
const browserslistEnv = process.env.BROWSERSLIST_ENV || defaultBrowserslistEnv;
if ( browserslistEnv === 'defaults' ) {
That said, I don't like the duplication of logic. What do you thing is the best way of handling things here, @jsnajdr? Should webpack.config.js
set the BROWSERSLIST_ENV
environment variable to the value of browserslistEnv
so that subprocesses like postcss
can reuse it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The webpack config can pass some arbitrary options down to the postcss-loader
and in turn to the postcss.config.js
file. They call it context.
The code that configures the SassLoader
will look like this:
SassConfig.loader( {
postCssConfig: {
path: __dirname,
ctx: {
transformCssProperties: isFallbackBuild
},
},
...
} )
Then the postcss.config.js
file can use the context: the ctx
object is exposed as options
:
module.exports = ( { options } ) => {
const { transformCssProperties } = options;
// return config object
}
I think this all is a good tool for this PR. The messy logic stays only at one place (the webpack config).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, that's a lot better than the environment variable! 👍
client/postcss.config.js
Outdated
autoprefixer: {}, | ||
}, | ||
} ); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is too much unneeded duplication in this code. Can it be like this?
module.exports = () => {
const plugins = {
autoprefixer: {},
};
if ( wantCustomProps ) {
plugins[ 'postcss-custom-properties' ] = { ... };
}
return { plugins };
}
Addressed all |
Timings i saw for before: after: The "total" times here are likely a touch off, as I'm just control-c'ing my way out to get them. But in the right ballpark. The main webpack build took Looks like this feature came to postcss in Should also report this back up to the postcss folks. |
There is a regression in IE. CSS vars are still there |
The line should be changed to: transformCssProperties: browserslistEnv === 'defaults', |
Anecdotally, this cuts calypso build time for me from 6 minutes to 3. 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new changes look good! 👍
forceFallback=1
shows both CSS custom properties and the precomputed color, as expected, whereas no forceFallback
doesn't show precomputed values, only CSS custom properties.
@nsakaimbo: Could you confirm that the desktop app still works correctly with these changes? We're looking for any errors in styles, most likely the colours being wrong. |
Desktop e2e failures in the build artifact - some sort of runtime error. It's happening consistently, although I don't think it's related to changes in this branch. Still looking...
|
Runtime error in the desktop app:
Unclear what's happening here, but I do see it in other Calypso branches as well. (It's not happening in wp-desktop develop branch, only in more recent Calypso PRs. So I'm guessing something was introduced since last submodule update that's driving this error.) |
@sgomes @alshakero This change looks great, except I'm unable to verify what it looks like as it seems latest Calypso isn't working in the desktop app (again - see the strange runtime error above). Unfortunately I'm unable to provide an assessment of whether there may be any unintended side effects here. |
2d51afc
to
cc68d6a
Compare
I did some debugging and I think that the The real problem is not that the We use the And every CSS file needs its own instance of the plugin, because the PostCSS configuration is dynamic: every file can have a different chain of directory-local Calypso webpack build creates 850 instances of the plugin, as that's the number of The Also, for every CSS variable in a block like this: :root {
--studio-white: #fff;
--studio-black: #000;
/* ... 170 more variables like this ... */
} the A |
Thanks for digging deep! This sounds great. If no one picked this up, I'll work on it on the weekend. I think we might need to create some sort of a benchmark to convince the plugin folks about the issue's significance. And to be able to compare before and after our PR. |
My experience is that performance improvements usually don't need much convincing. Calypso build timings before and after should be enough. There are two improvements that I expect to be impactful:
|
@nsakaimbo I can't reproduce the runtime error in the Do I need to go to any specific section to reproduce? |
Thanks a ton @alshakero and @jsnajdr for your investigations! ✨ It'd be great if we could fix this upstream so that other A8c projects that use (It would be otherwise conceivable to add an option to |
Update: been trying to triage this and I think I might have narrowed down the break in the desktop app. Created a new issue with details: #42898 cc: @belcherj @griffbrad |
Thanks @nsakaimbo! Do I understand correctly that wp-desktop fails on Calypso#master too? Can we merge this given it's inconsequential to that issue? |
Answering for @nsakaimbo: yes, |
Alright, so I created an issue to triage the plugin and I'll merge this. |
Build performance improvement
Yesterday, using Webpack ProfilingPlugin, I did an audit for our build performance to look for low hanging fruits, and did I find one.
It turns out there is a single line in
postcss-custom-properties
that is more than doubling ouryarn start
time 🤯 .Ironically, we never make any use of this line. It detects
postcss-custom-properties: ignore next|off
CSS comments to disable the plugin for the block that contains this comment. We don't have any of these comments so we're wasting a lot of time for nothing.I spent some time trying to make the package faster by using some crafted string manipulation logic instead of a regex. But it never got considerably faster. The
isBlockIgnored
is called a lot, it seems.After a second thought, it occured to me that CSS custom properties are supported everywhere now except in IE11. IE11 is not supported in our development build anyways, so compiling CSS custom properties down to static values is a total waste of time in development, with the only benefit of shrinking the difference between our prod and development builds. I think slashing the time by half is more than worth this sacrifice.
Testing instructions
The perf difference
yarn start
on master and time it until you seeReady! You can load http://calypso.localhost:3000/ now. Have fun!
.On my machine it went down from 2:46 to 1:01.
The CSS outcome