Skip to content

Commit 7308dd0

Browse files
authored
[system] Pre-serialize & cache styles to improve performance (#43412)
1 parent e6ff0b5 commit 7308dd0

File tree

16 files changed

+718
-588
lines changed

16 files changed

+718
-588
lines changed

apps/pigment-css-next-app/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"react-dom": "^18.3.1"
2424
},
2525
"devDependencies": {
26-
"@pigment-css/nextjs-plugin": "0.0.23",
26+
"@pigment-css/nextjs-plugin": "0.0.24",
2727
"@types/node": "^20.16.5",
2828
"@types/react": "^18.3.6",
2929
"@types/react-dom": "^18.3.0",

apps/pigment-css-vite-app/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"devDependencies": {
2828
"@babel/preset-react": "^7.24.7",
2929
"@babel/preset-typescript": "^7.24.7",
30-
"@pigment-css/vite-plugin": "0.0.23",
30+
"@pigment-css/vite-plugin": "0.0.24",
3131
"@types/react": "^18.3.6",
3232
"@types/react-dom": "^18.3.0",
3333
"@types/webfontloader": "^1.6.38",

package.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
"@mui/utils": "workspace:^",
127127
"@next/eslint-plugin-next": "^14.2.13",
128128
"@octokit/rest": "^21.0.2",
129-
"@pigment-css/react": "0.0.23",
129+
"@pigment-css/react": "0.0.24",
130130
"@playwright/test": "1.47.2",
131131
"@types/babel__core": "^7.20.5",
132132
"@types/fs-extra": "^11.0.4",
@@ -219,10 +219,10 @@
219219
"@types/react": "^18.3.6",
220220
"@types/react-dom": "18.3.0",
221221
"cross-fetch": "^4.0.0",
222-
"@pigment-css/react": "0.0.23",
223-
"@pigment-css/unplugin": "0.0.23",
224-
"@pigment-css/nextjs-plugin": "0.0.23",
225-
"@pigment-css/vite-plugin": "0.0.23"
222+
"@pigment-css/react": "0.0.24",
223+
"@pigment-css/unplugin": "0.0.24",
224+
"@pigment-css/nextjs-plugin": "0.0.24",
225+
"@pigment-css/vite-plugin": "0.0.24"
226226
},
227227
"nyc": {
228228
"include": [

packages/mui-material-pigment-css/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"dependencies": {
4242
"@babel/runtime": "^7.25.6",
4343
"@mui/system": "workspace:*",
44-
"@pigment-css/react": "0.0.23"
44+
"@pigment-css/react": "0.0.24"
4545
},
4646
"sideEffects": false,
4747
"publishConfig": {
+3-28
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,6 @@
1-
import { CSSInterpolation } from '@mui/system';
1+
import { unstable_memoTheme } from '@mui/system';
22
import { Theme } from '../styles/createTheme';
33

4-
type ThemeStyleFunction = (props: { theme: Theme }) => CSSInterpolation;
4+
const memoTheme = unstable_memoTheme<Theme>;
55

6-
// We need to pass an argument as `{ theme }` for PigmentCSS, but we don't want to
7-
// allocate more objects.
8-
const arg = { theme: undefined as unknown as Theme };
9-
10-
/**
11-
* Memoize style function on theme.
12-
* Intended to be used in styled() calls that only need access to the theme.
13-
*/
14-
export default function memoTheme(styleFn: ThemeStyleFunction) {
15-
let lastValue: CSSInterpolation;
16-
let lastTheme: Theme;
17-
18-
return (props: { theme: Theme }) => {
19-
let value = lastValue;
20-
if (value === undefined || props.theme !== lastTheme) {
21-
arg.theme = props.theme;
22-
23-
value = styleFn(arg);
24-
25-
lastValue = value;
26-
lastTheme = props.theme;
27-
}
28-
29-
return value;
30-
};
31-
}
6+
export default memoTheme;

packages/mui-styled-engine-sc/src/index.d.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,14 @@ export * from './GlobalStyles';
7676
* For internal usage in `@mui/system` package
7777
*/
7878
// eslint-disable-next-line @typescript-eslint/naming-convention
79-
export function internal_processStyles(
79+
export function internal_mutateStyles(
8080
tag: React.ElementType,
8181
processor: (styles: any) => any,
8282
): void;
8383

84+
// eslint-disable-next-line @typescript-eslint/naming-convention
85+
export function internal_serializeStyles<P>(styles: Interpolation<P>): object;
86+
8487
// These are the same as the ones in @mui/styled-engine
8588
// CSS.PropertiesFallback are necessary so that we support spreading of the mixins. For example:
8689
// '@font-face'?: Fontface | Fontface[]

packages/mui-styled-engine-sc/src/index.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default function styled(tag, options) {
3737
}
3838

3939
// eslint-disable-next-line @typescript-eslint/naming-convention
40-
export const internal_processStyles = (tag, processor) => {
40+
export function internal_mutateStyles(tag, processor) {
4141
// Styled-components attaches an instance to `componentStyle`.
4242
// https://github.com/styled-components/styled-components/blob/da8151762dcf72735ffba358173d4c097f6d5888/packages/styled-components/src/models/StyledComponent.ts#L257
4343
//
@@ -46,7 +46,12 @@ export const internal_processStyles = (tag, processor) => {
4646
if (tag.componentStyle) {
4747
tag.componentStyle.rules = processor(tag.componentStyle.rules);
4848
}
49-
};
49+
}
50+
51+
// eslint-disable-next-line @typescript-eslint/naming-convention
52+
export function internal_serializeStyles(styles) {
53+
return styles;
54+
}
5055

5156
export { ThemeContext, keyframes, css } from 'styled-components';
5257
export { default as StyledEngineProvider } from './StyledEngineProvider';

packages/mui-styled-engine/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"dependencies": {
4040
"@babel/runtime": "^7.25.6",
4141
"@emotion/cache": "^11.13.1",
42+
"@emotion/serialize": "^1.3.1",
4243
"@emotion/sheet": "^1.4.0",
4344
"csstype": "^3.1.3",
4445
"prop-types": "^15.8.1"

packages/mui-styled-engine/src/index.d.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@ export type MUIStyledComponent<
2121
* For internal usage in `@mui/system` package
2222
*/
2323
// eslint-disable-next-line @typescript-eslint/naming-convention
24-
export function internal_processStyles(
24+
export function internal_mutateStyles(
2525
tag: React.ElementType,
2626
processor: (styles: any) => any,
2727
): void;
2828

29+
// eslint-disable-next-line @typescript-eslint/naming-convention
30+
export function internal_serializeStyles<P>(styles: Interpolation<P>): object;
31+
2932
export interface SerializedStyles {
3033
name: string;
3134
styles: string;

packages/mui-styled-engine/src/index.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable no-underscore-dangle */
22
import emStyled from '@emotion/styled';
3+
import { serializeStyles as emSerializeStyles } from '@emotion/serialize';
34

45
export default function styled(tag, options) {
56
const stylesFactory = emStyled(tag, options);
@@ -27,13 +28,21 @@ export default function styled(tag, options) {
2728
}
2829

2930
// eslint-disable-next-line @typescript-eslint/naming-convention
30-
export const internal_processStyles = (tag, processor) => {
31+
export function internal_mutateStyles(tag, processor) {
3132
// Emotion attaches all the styles as `__emotion_styles`.
3233
// Ref: https://github.com/emotion-js/emotion/blob/16d971d0da229596d6bcc39d282ba9753c9ee7cf/packages/styled/src/base.js#L186
3334
if (Array.isArray(tag.__emotion_styles)) {
3435
tag.__emotion_styles = processor(tag.__emotion_styles);
3536
}
36-
};
37+
}
38+
39+
// Emotion only accepts an array, but we want to avoid allocations
40+
const wrapper = [];
41+
// eslint-disable-next-line @typescript-eslint/naming-convention
42+
export function internal_serializeStyles(styles) {
43+
wrapper[0] = styles;
44+
return emSerializeStyles(wrapper);
45+
}
3746

3847
export { ThemeContext, keyframes, css } from '@emotion/react';
3948
export { default as StyledEngineProvider } from './StyledEngineProvider';

0 commit comments

Comments
 (0)