Skip to content

Commit

Permalink
[system] Pre-serialize & cache styles to improve performance (#43412)
Browse files Browse the repository at this point in the history
  • Loading branch information
romgrk authored Oct 2, 2024
1 parent e6ff0b5 commit 7308dd0
Show file tree
Hide file tree
Showing 16 changed files with 718 additions and 588 deletions.
2 changes: 1 addition & 1 deletion apps/pigment-css-next-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"react-dom": "^18.3.1"
},
"devDependencies": {
"@pigment-css/nextjs-plugin": "0.0.23",
"@pigment-css/nextjs-plugin": "0.0.24",
"@types/node": "^20.16.5",
"@types/react": "^18.3.6",
"@types/react-dom": "^18.3.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/pigment-css-vite-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"devDependencies": {
"@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.24.7",
"@pigment-css/vite-plugin": "0.0.23",
"@pigment-css/vite-plugin": "0.0.24",
"@types/react": "^18.3.6",
"@types/react-dom": "^18.3.0",
"@types/webfontloader": "^1.6.38",
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
"@mui/utils": "workspace:^",
"@next/eslint-plugin-next": "^14.2.13",
"@octokit/rest": "^21.0.2",
"@pigment-css/react": "0.0.23",
"@pigment-css/react": "0.0.24",
"@playwright/test": "1.47.2",
"@types/babel__core": "^7.20.5",
"@types/fs-extra": "^11.0.4",
Expand Down Expand Up @@ -219,10 +219,10 @@
"@types/react": "^18.3.6",
"@types/react-dom": "18.3.0",
"cross-fetch": "^4.0.0",
"@pigment-css/react": "0.0.23",
"@pigment-css/unplugin": "0.0.23",
"@pigment-css/nextjs-plugin": "0.0.23",
"@pigment-css/vite-plugin": "0.0.23"
"@pigment-css/react": "0.0.24",
"@pigment-css/unplugin": "0.0.24",
"@pigment-css/nextjs-plugin": "0.0.24",
"@pigment-css/vite-plugin": "0.0.24"
},
"nyc": {
"include": [
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-material-pigment-css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"dependencies": {
"@babel/runtime": "^7.25.6",
"@mui/system": "workspace:*",
"@pigment-css/react": "0.0.23"
"@pigment-css/react": "0.0.24"
},
"sideEffects": false,
"publishConfig": {
Expand Down
31 changes: 3 additions & 28 deletions packages/mui-material/src/utils/memoTheme.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,6 @@
import { CSSInterpolation } from '@mui/system';
import { unstable_memoTheme } from '@mui/system';
import { Theme } from '../styles/createTheme';

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

// We need to pass an argument as `{ theme }` for PigmentCSS, but we don't want to
// allocate more objects.
const arg = { theme: undefined as unknown as Theme };

/**
* Memoize style function on theme.
* Intended to be used in styled() calls that only need access to the theme.
*/
export default function memoTheme(styleFn: ThemeStyleFunction) {
let lastValue: CSSInterpolation;
let lastTheme: Theme;

return (props: { theme: Theme }) => {
let value = lastValue;
if (value === undefined || props.theme !== lastTheme) {
arg.theme = props.theme;

value = styleFn(arg);

lastValue = value;
lastTheme = props.theme;
}

return value;
};
}
export default memoTheme;
5 changes: 4 additions & 1 deletion packages/mui-styled-engine-sc/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,14 @@ export * from './GlobalStyles';
* For internal usage in `@mui/system` package
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
export function internal_processStyles(
export function internal_mutateStyles(
tag: React.ElementType,
processor: (styles: any) => any,
): void;

// eslint-disable-next-line @typescript-eslint/naming-convention
export function internal_serializeStyles<P>(styles: Interpolation<P>): object;

// These are the same as the ones in @mui/styled-engine
// CSS.PropertiesFallback are necessary so that we support spreading of the mixins. For example:
// '@font-face'?: Fontface | Fontface[]
Expand Down
9 changes: 7 additions & 2 deletions packages/mui-styled-engine-sc/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function styled(tag, options) {
}

// eslint-disable-next-line @typescript-eslint/naming-convention
export const internal_processStyles = (tag, processor) => {
export function internal_mutateStyles(tag, processor) {
// Styled-components attaches an instance to `componentStyle`.
// https://github.com/styled-components/styled-components/blob/da8151762dcf72735ffba358173d4c097f6d5888/packages/styled-components/src/models/StyledComponent.ts#L257
//
Expand All @@ -46,7 +46,12 @@ export const internal_processStyles = (tag, processor) => {
if (tag.componentStyle) {
tag.componentStyle.rules = processor(tag.componentStyle.rules);
}
};
}

// eslint-disable-next-line @typescript-eslint/naming-convention
export function internal_serializeStyles(styles) {
return styles;
}

export { ThemeContext, keyframes, css } from 'styled-components';
export { default as StyledEngineProvider } from './StyledEngineProvider';
Expand Down
1 change: 1 addition & 0 deletions packages/mui-styled-engine/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"dependencies": {
"@babel/runtime": "^7.25.6",
"@emotion/cache": "^11.13.1",
"@emotion/serialize": "^1.3.1",
"@emotion/sheet": "^1.4.0",
"csstype": "^3.1.3",
"prop-types": "^15.8.1"
Expand Down
5 changes: 4 additions & 1 deletion packages/mui-styled-engine/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ export type MUIStyledComponent<
* For internal usage in `@mui/system` package
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
export function internal_processStyles(
export function internal_mutateStyles(
tag: React.ElementType,
processor: (styles: any) => any,
): void;

// eslint-disable-next-line @typescript-eslint/naming-convention
export function internal_serializeStyles<P>(styles: Interpolation<P>): object;

export interface SerializedStyles {
name: string;
styles: string;
Expand Down
13 changes: 11 additions & 2 deletions packages/mui-styled-engine/src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-underscore-dangle */
import emStyled from '@emotion/styled';
import { serializeStyles as emSerializeStyles } from '@emotion/serialize';

export default function styled(tag, options) {
const stylesFactory = emStyled(tag, options);
Expand Down Expand Up @@ -27,13 +28,21 @@ export default function styled(tag, options) {
}

// eslint-disable-next-line @typescript-eslint/naming-convention
export const internal_processStyles = (tag, processor) => {
export function internal_mutateStyles(tag, processor) {
// Emotion attaches all the styles as `__emotion_styles`.
// Ref: https://github.com/emotion-js/emotion/blob/16d971d0da229596d6bcc39d282ba9753c9ee7cf/packages/styled/src/base.js#L186
if (Array.isArray(tag.__emotion_styles)) {
tag.__emotion_styles = processor(tag.__emotion_styles);
}
};
}

// Emotion only accepts an array, but we want to avoid allocations
const wrapper = [];
// eslint-disable-next-line @typescript-eslint/naming-convention
export function internal_serializeStyles(styles) {
wrapper[0] = styles;
return emSerializeStyles(wrapper);
}

export { ThemeContext, keyframes, css } from '@emotion/react';
export { default as StyledEngineProvider } from './StyledEngineProvider';
Expand Down
Loading

0 comments on commit 7308dd0

Please sign in to comment.