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
[system] Various perf gain experiments #23688
Conversation
This comment has been minimized.
This comment has been minimized.
@mnajdova What do you think about ignoring these metrics (removing them from the benchmark):
and focusing on the end-to-end version: |
@mnajdova We might want to rewrite the system to iterate on the props instead of calling each transformation. I think that Theme-UI and Chakra-UI have demonstrated that it can be faster unless it's their cache that helps the most. I think that it will make it easier to scale to custom transformations without impacting runtime cost. For instance, what if I want to add a & > * + * {
margin-right: 8px;
} @mbrookes a reference to #18459 (review). |
This is how the sx style function works right now. Let's remove from it the support for all other box props and see if there will be some perf gain. Focusing only on that one can be more productive :) |
@@ -26,7 +26,7 @@ export default function deepmerge<T>( | |||
return; | |||
} | |||
|
|||
if (isPlainObject(source[key]) && key in target) { | |||
if (isPlainObject(source[key]) && key in target && isPlainObject(target[key])) { |
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.
We need deepmerge
only if both source and target are objects. Otherwise we can override with source[key]
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.
These look like overall improvements :).
One thing that could be interesting is to benchmark, on the Node.js side (what we call server) is the performance of the system raw, meaning sx transformation method vs. https://styled-system.com/css vs. import { css } from '@chakra-ui/styled-system'
. The function that converts the superset of CSS into CSS. And remove the benchmark on the lower-level methods, like color, compose, etc.
I was trying this method already, seems like in order to be equivalent we need to run |
Opened #23702 for updating benchmarks. Will extract PRs from this one along te way for the changes we agree are good to go :) Will keep this one as a hub for trying all changes |
After merging #23716 I think this can be opened as a standalone PR. |
} | ||
return acc; | ||
}, | ||
{ ...style }, |
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.
No need for cloning
@@ -1,4 +1,4 @@ | |||
import { deepmerge } from '@material-ui/utils'; | |||
import merge from './merge'; |
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.
merge
is more suited and performant for these use-cases than deepmerge
- it returns early for null args + doesn't clone the first arg.
@@ -48,25 +52,25 @@ function styleFunctionSx(props) { | |||
let css = {}; | |||
|
|||
Object.keys(styles).forEach((styleKey) => { | |||
if (typeof styles[styleKey] === 'object') { | |||
const value = callIfFn(styles[styleKey], theme); |
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.
This was wrong previously, if the value is a function we need to resolve it and do the rest of the logic.
…jdova/material-ui into feat/perf-system-experiments
@@ -127,7 +127,7 @@ describe('styleFunctionSx', () => { | |||
xl: 0.5, | |||
}, | |||
border: [1, 2, 3], | |||
borderColor: (t) => t.palette.secondary.main, | |||
borderColor: (t) => [t.palette.secondary.main, t.palette.primary.main], |
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.
Updated tests for the function changes implemented here https://github.com/mui-org/material-ui/pull/23688/files#r530971112
@oliviertassinari trying the React.Profiler - #23731 results don't look much more stable either... :\ |
I have noticed that when I switch windows during the run of the tests, I get a spike of std. Two ideas to reduce it, no idea if it works:
But maybe it's already good enough. Maybe we should focus on identifying the slowest path, fix it, iterate. We can learn from existing alternative implementations. |
Agree, this first round is just about small improvements that can immediately be fixed and seems like we are now comparable with Next, I will try to see if restructuring the whole code will make much difference, but would like to have this one in first, to compare the difference based on these new numbers |
Trying various micro-optimizations, nothing big found at this moment yet