Skip to content

Commit

Permalink
Appearance: Cache colorScheme in JavaScript (#46122)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #46122

Implements a JavaScript cache for `colorScheme` in the `Appearance` module, so that we avoid potentially expensive and unnecessary native property accesses.

Changelog:
[General][Changed] - Improved `Appearance.getColorScheme` performance

Reviewed By: rickhanlonii

Differential Revision: D61567880
  • Loading branch information
yungsters authored and facebook-github-bot committed Aug 21, 2024
1 parent 0a0bd0d commit 92f8f7a
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions packages/react-native/Libraries/Utilities/Appearance.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ type NativeAppearanceEventDefinitions = {
appearanceChanged: [AppearancePreferences],
};

// Cache the color scheme to reduce the cost of reading it between changes.
// NOTE: If `NativeAppearance` is null, this will always be null.
let appearance: ?{colorScheme: ?ColorSchemeName} = null;

if (NativeAppearance != null) {
new NativeEventEmitter<NativeAppearanceEventDefinitions>(
NativeAppearance,
).addListener('appearanceChanged', (newAppearance: AppearancePreferences) => {
const colorScheme = toColorScheme(newAppearance.colorScheme);
eventEmitter.emit('change', {colorScheme});
appearance = {colorScheme};
eventEmitter.emit('change', appearance);
});
}

Expand All @@ -49,14 +54,28 @@ export function getColorScheme(): ?ColorSchemeName {
return 'light';
}
}
return toColorScheme(NativeAppearance?.getColorScheme());
let colorScheme = null;
if (NativeAppearance != null) {
if (appearance == null) {
// Lazily initialize `appearance`. This should only happen once because
// we never reassign a null value to `appearance`.
appearance = {
colorScheme: toColorScheme(NativeAppearance.getColorScheme()),
};
}
colorScheme = appearance.colorScheme;
}
return colorScheme;
}

/**
* Updates the current color scheme to the supplied value.
*/
export function setColorScheme(colorScheme: ?ColorSchemeName): void {
NativeAppearance?.setColorScheme(toColorScheme(colorScheme) ?? 'unspecified');
if (NativeAppearance != null) {
NativeAppearance.setColorScheme(colorScheme ?? 'unspecified');
appearance = {colorScheme};
}
}

/**
Expand Down

0 comments on commit 92f8f7a

Please sign in to comment.