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
Todo core
Todo webpack plugin
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
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,:
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
Todo babel plugin
@rawrule into the styles declarationTodo core
classesto createStyleSheet@rawplugin, add it to default preset@rawwith equivalent style objectsTodo webpack plugin
@rawruleFuture enhancements
{padding: (props) => props.spacing, paddingLeft: 10}after compilation paddingLeft will be overwritten by padding since it will have higher source order specificityjss/staticfor a reduced version of jss which does not include any plugins etc logic, since it is all preprocessed (unless we can treeshake it???)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