Skip to content

Commit 1536786

Browse files
perf: defer styles computation from module import to provider render
1 parent da7adae commit 1536786

File tree

8 files changed

+49
-29
lines changed

8 files changed

+49
-29
lines changed
Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
1-
// eslint-disable-next-line no-restricted-imports
2-
import {defaultStyles} from '@styles/index';
3-
// eslint-disable-next-line no-restricted-imports
4-
import {DefaultStyleUtils} from '@styles/utils';
1+
import styles from '@src/styles';
2+
import {defaultTheme} from '@src/styles/theme';
3+
import createStyleUtils from '@src/styles/utils';
54
import type {ThemeStylesActionsContextType, ThemeStylesStateContextType} from './types';
65

7-
const defaultThemeStylesStateContextValue: ThemeStylesStateContextType = {
8-
styles: defaultStyles,
9-
};
6+
// Lazy defaults: defers the expensive styles(defaultTheme) call from module import
7+
// time to first access. In production, ThemeStylesProvider supplies real values so
8+
// these are never reached. Tests that render without the provider will trigger lazy
9+
// initialization on first access.
10+
let cachedState: ThemeStylesStateContextType | undefined;
11+
let cachedActions: ThemeStylesActionsContextType | undefined;
1012

11-
const defaultThemeStylesActionsContextValue: ThemeStylesActionsContextType = {
12-
StyleUtils: DefaultStyleUtils,
13-
};
13+
const defaultThemeStylesStateContextValue = new Proxy({} as ThemeStylesStateContextType, {
14+
get(_, prop: keyof ThemeStylesStateContextType) {
15+
if (!cachedState) {
16+
cachedState = {styles: styles(defaultTheme)};
17+
}
18+
return cachedState[prop];
19+
},
20+
});
21+
22+
const defaultThemeStylesActionsContextValue = new Proxy({} as ThemeStylesActionsContextType, {
23+
get(_, prop: keyof ThemeStylesActionsContextType) {
24+
if (!cachedActions) {
25+
if (!cachedState) {
26+
cachedState = {styles: styles(defaultTheme)};
27+
}
28+
cachedActions = {StyleUtils: createStyleUtils(defaultTheme, cachedState.styles)};
29+
}
30+
return cachedActions[prop];
31+
},
32+
});
1433

1534
export {defaultThemeStylesStateContextValue, defaultThemeStylesActionsContextValue};

src/stories/CheckboxWithLabel.stories.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import React from 'react';
33
import CheckboxWithLabel from '@components/CheckboxWithLabel';
44
import type {CheckboxWithLabelProps} from '@components/CheckboxWithLabel';
55
import Text from '@components/Text';
6-
// eslint-disable-next-line no-restricted-imports
7-
import {defaultStyles} from '@styles/index';
6+
import styles from '@src/styles';
7+
import {defaultTheme} from '@src/styles/theme';
8+
9+
const defaultStyles = styles(defaultTheme);
810

911
type CheckboxWithLabelStory = StoryFn<typeof CheckboxWithLabel>;
1012

src/stories/Composer.stories.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import RenderHTML from '@components/RenderHTML';
99
import Text from '@components/Text';
1010
import withNavigationFallback from '@components/withNavigationFallback';
1111
import useStyleUtils from '@hooks/useStyleUtils';
12-
// eslint-disable-next-line no-restricted-imports
13-
import {defaultTheme} from '@styles/theme';
14-
import {defaultStyles} from '@src/styles';
12+
import styles from '@src/styles';
13+
import {defaultTheme} from '@src/styles/theme';
1514
import type {FileObject} from '@src/types/utils/Attachment';
1615

16+
const defaultStyles = styles(defaultTheme);
17+
1718
const ComposerWithNavigation = withNavigationFallback(Composer);
1819

1920
/**

src/stories/DragAndDrop.stories.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import {Image, View} from 'react-native';
44
import DragAndDropConsumer from '@components/DragAndDrop/Consumer';
55
import DragAndDropProvider from '@components/DragAndDrop/Provider';
66
import Text from '@components/Text';
7-
import {defaultStyles} from '@src/styles';
7+
import styles from '@src/styles';
8+
import {defaultTheme} from '@src/styles/theme';
9+
10+
const defaultStyles = styles(defaultTheme);
811

912
/**
1013
* We use the Component Story Format for writing stories. Follow the docs here:

src/stories/Form.stories.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ import {isRequiredFulfilled} from '@libs/ValidationUtils';
1818
import {clearErrors, setDraftValues, setErrors, setIsLoading} from '@userActions/FormActions';
1919
import CONST from '@src/CONST';
2020
import type {OnyxFormValuesMapping} from '@src/ONYXKEYS';
21-
import {defaultStyles} from '@src/styles';
21+
import styles from '@src/styles';
22+
import {defaultTheme} from '@src/styles/theme';
2223
import type {Form} from '@src/types/form';
2324
import type {Network} from '@src/types/onyx';
2425

26+
const defaultStyles = styles(defaultTheme);
27+
2528
type FormStory = StoryFn<FormProviderProps & FormProviderOnyxProps>;
2629

2730
type StorybookFormValues = {

src/stories/NumberWithSymbolForm.stories.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import NumberWithSymbolForm from '@components/NumberWithSymbolForm';
55
import type {NumberWithSymbolFormProps} from '@components/NumberWithSymbolForm';
66
import ScrollView from '@components/ScrollView';
77
import withNavigationFallback from '@components/withNavigationFallback';
8-
// eslint-disable-next-line no-restricted-imports
9-
import {defaultStyles} from '@styles/index';
108
import CONST from '@src/CONST';
9+
import styles from '@src/styles';
10+
import {defaultTheme} from '@src/styles/theme';
11+
12+
const defaultStyles = styles(defaultTheme);
1113

1214
type NumberWithSymbolFormStory = StoryFn<typeof NumberWithSymbolForm>;
1315

src/styles/index.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {getBrowser, isMobile, isMobileSafari, isSafari} from '@libs/Browser';
1919
import getPlatform from '@libs/getPlatform';
2020
import CONST from '@src/CONST';
2121
import type {Dimensions} from '@src/types/utils/Layout';
22-
import {defaultTheme} from './theme';
2322
import colors from './theme/colors';
2423
import type {ThemeColors} from './theme/types';
2524
import addOutlineWidth from './utils/addOutlineWidth';
@@ -6559,8 +6558,5 @@ const styles = (theme: ThemeColors) =>
65596558

65606559
type ThemeStyles = ReturnType<typeof styles>;
65616560

6562-
const defaultStyles = styles(defaultTheme);
6563-
65646561
export default styles;
6565-
export {defaultStyles};
65666562
export type {ThemeStyles, StatusBarStyle, ColorScheme, AnchorPosition, AnchorDimensions, OverlayStylesParams};

src/styles/utils/index.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,13 @@ import {LETTER_AVATAR_COLOR_OPTIONS} from '@libs/Avatars/PresetAvatarCatalog';
99
import {isMobile, isMobileChrome} from '@libs/Browser';
1010
import getPlatform from '@libs/getPlatform';
1111
import {hashText} from '@libs/UserUtils';
12-
// eslint-disable-next-line no-restricted-imports
13-
import {defaultTheme} from '@styles/theme';
1412
import colors from '@styles/theme/colors';
1513
import type {ThemeColors} from '@styles/theme/types';
1614
import variables from '@styles/variables';
1715
import CONST from '@src/CONST';
1816
import type {Transaction} from '@src/types/onyx';
1917
import type {Dimensions} from '@src/types/utils/Layout';
2018
import type Nullable from '@src/types/utils/Nullable';
21-
import {defaultStyles} from '..';
2219
import type {ThemeStyles} from '..';
2320
import shouldPreventScrollOnAutoCompleteSuggestion from './autoCompleteSuggestion';
2421
import getCardStyles from './cardStyles';
@@ -2291,8 +2288,5 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({
22912288

22922289
type StyleUtilsType = ReturnType<typeof createStyleUtils>;
22932290

2294-
const DefaultStyleUtils = createStyleUtils(defaultTheme, defaultStyles);
2295-
22962291
export default createStyleUtils;
2297-
export {DefaultStyleUtils};
22982292
export type {StyleUtilsType, AvatarSizeName};

0 commit comments

Comments
 (0)