-
-
Notifications
You must be signed in to change notification settings - Fork 402
Open
Labels
complexity:highBest brains need to talk about it.Best brains need to talk about it.feature requestThis will safe many lifes!This will safe many lifes!importantThe thing you do when you wake up!The thing you do when you wake up!perf
Description
The idea is to optimize it in a way that shifts preprocessing runtime overhead to the build stage, while keeping all dynamic parts working. It includes 2 stages: one is babel plugin, another is webpack plugin.
With full extraction,:
- There will be no static styles at runtime that need to be parsed and injected (only dynamic)
- No double loading of static styles in JS build + CSS build.
With babel plugin only there will be no runtime processing of static styles, only dynamic. Current state is that jss core without plugins with styles object vs preprocessed version of the same object results in 50% performance boost.
Exmple
// source js
const styles = {
static: {
color: 'green'
},
mixed: {
color: 'red',
margin: (props) => props.spacing
}
}
createStyleSheet(styles).attach()
// generated js
const styles = {
'@raw': `
.static-0-0-1 {
color: green;
}
.mixed-0-0-2 {
color: red;
}
`,
mixed: {
margin: (props) => props.spacing
}
}
const {classes} = createStyleSheet(styles, {
classes: {
static: 'static-0-0-1',
mixed: 'mixed-0-0-2'
}
}).attach()
Todo babel plugin
- Identify injectSheet(styles, options), createStyleSheet(styles, options) calls, make it customizable for different function names.
- allow to pass jss config to the babel plugin
- extract static styles object literal
- extract static styles from the reference
- extract any value from reference
- extract sheet options if provided
- extract sheet options from reference
- extract sheet options nested properties from reference
- create jss with plugins => createStyleSheet(styles, options).toString()
- insert static css as a
@raw
rule into the styles declaration - remove original static styles
- pass classes map from static sheet as options
- math expressions
- function call results
- css preprocessing pipeline (with postcss)
- autoprefixer
- babel like theming configuration over file system in any directory????
Todo core
- implement option
classes
to createStyleSheet - implement
@raw
plugin, add it to default preset - make a bench comparing
@raw
with equivalent style objects - docs
- blogpost?
Todo webpack plugin
- identify
@raw
rule - extract css
- remove the rule
- provide the css to webpack so that other loaders can use it (tbd how)
Future enhancements
- Think of potential solution to the problem:
{padding: (props) => props.spacing, paddingLeft: 10}
after compilation paddingLeft will be overwritten by padding since it will have higher source order specificity - If static CSS is used without critical CSS over SSR, dynamic styles are not part of the static bundle and styling is incomplete. Think of a strategy to warn/require default values for dynamic styles.
- a demo app with webpack/postcss/css-modules/autoprefixer
- When there are no dynamic styles, remove all jss runtime code from the module
- When function values/rules are not using props and can be statically extracted (see linaria)
- Separate entry point
jss/static
for a reduced version of jss which does not include any plugins etc logic, since it is all preprocessed (unless we can treeshake it???) - Remove unused styles or warn when any detected, see this and the article for e.g.
Some inspiration can be taken from
https://github.com/4Catalyzer/css-literal-loader
https://github.com/callstack-io/linaria
https://www.npmjs.com/package/extract-jss-webpack-plugin
boyarskiy, auwtch, gpoitch, mehrdad-shokri, giancarlosisasi and 19 moreivawzh and vovacodes
Metadata
Metadata
Assignees
Labels
complexity:highBest brains need to talk about it.Best brains need to talk about it.feature requestThis will safe many lifes!This will safe many lifes!importantThe thing you do when you wake up!The thing you do when you wake up!perf