Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

perf: cache component variables #2041

Merged
merged 8 commits into from
Oct 18, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Performance
- Remove redundant usages of `Box` component in `Attachment`, `Popup` and `Tooltip` @layershifter ([#2023](https://github.com/stardust-ui/react/pull/2023))
- Refactor `ListItem` to avoid usages of `Flex` component @layershifter ([#2025](https://github.com/stardust-ui/react/pull/2025))
- Cache resolved component variables @jurokapsiar @miroslavstastny ([#2041](https://github.com/stardust-ui/react/pull/2041))

<!--------------------------------[ v0.40.0 ]------------------------------- -->
## [v0.40.0](https://github.com/stardust-ui/react/tree/v0.40.0) (2019-10-09)
Expand Down
10 changes: 7 additions & 3 deletions packages/react/src/lib/mergeProviderContexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ export const mergeBooleanValues = (target, ...sources) => {
const mergeProviderContexts = (
...contexts: (ProviderContextInput | ProviderContextPrepared)[]
): ProviderContextPrepared => {
const emptyContext = {
const emptyContext: ProviderContextPrepared = {
theme: {
siteVariables: {},
siteVariables: {
fontSizes: {},
},
componentVariables: {},
componentStyles: {},
fontFaces: [],
Expand All @@ -53,7 +55,9 @@ const mergeProviderContexts = (
disableAnimations: false,
originalThemes: [],
target: document, // eslint-disable-line no-undef
} as ProviderContextPrepared
_internal_resolvedComponentVariables: {},
renderer: undefined,
}

return contexts.reduce<ProviderContextPrepared>(
(acc: ProviderContextPrepared, next: ProviderContextInput | ProviderContextPrepared) => {
Expand Down
27 changes: 20 additions & 7 deletions packages/react/src/lib/renderComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,30 @@ const renderComponent = <P extends {}>(
logProviderMissingWarning()
}

const { disableAnimations = false, renderer = null, rtl = false, theme = emptyTheme } =
context || {}
const {
disableAnimations = false,
renderer = null,
rtl = false,
theme = emptyTheme,
_internal_resolvedComponentVariables: resolvedComponentVariables = {},
} = context || {}

const ElementType = getElementType(props) as React.ReactType<P>
const stateAndProps = { ...state, ...props }

// Resolve variables for this component, allow props.variables to override
const resolvedVariables: ComponentVariablesObject = mergeComponentVariables(
theme.componentVariables[displayName],
props.variables && withDebugId(props.variables, 'props.variables'),
)(theme.siteVariables)
// Resolve variables for this component, cache the result in provider
if (!resolvedComponentVariables[displayName]) {
resolvedComponentVariables[displayName] =
callable(theme.componentVariables[displayName])(theme.siteVariables) || {} // component variables must not be undefined/null (see mergeComponentVariables contract)
}

// Merge inline variables on top of cached variables
const resolvedVariables = props.variables
? mergeComponentVariables(
resolvedComponentVariables[displayName],
withDebugId(props.variables, 'props.variables'),
)(theme.siteVariables)
: resolvedComponentVariables[displayName]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, it's hard to read this, I suggest

let resolvedVariables = resolvedComponentVariables[displayName]

if (props.variables) {
  resolvedVariables = mergeComponentVariables(
    resolvedComponentVariables[displayName],
    withDebugId(props.variables, 'props.variables'),
  )(theme.siteVariables)
}

Copy link
Member Author

@miroslavstastny miroslavstastny Oct 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like let.


const animationCSSProp = props.animation
? createAnimationStyles(props.animation, context.theme)
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,5 @@ export interface ProviderContextPrepared {
target: Document
theme: ThemePrepared
originalThemes: (ThemeInput | undefined)[]
_internal_resolvedComponentVariables: Record<string, object>
}