StyleSheet API
This issue is for supporting a styles API similar to React Native's StyleSheet: http://reactnative.dev/docs/stylesheet
Currently all of our style props are passed inline to any given view component during each render pass. This works fine, but I suspect we'll gain a lot in terms of performance by switching to a stylesheet API. The goal here is that instead of writing our styles as we have been, we will instead write:
function MyView(props) {
return (<View style={styles.container}>{props.children}</View>);
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'red',
padding: 20,
}
});
This is a subtle change, but the point is this:
- During the creation of a StyleSheet with
StyleSheet.createwe can immediately marshal all the style properties over to native where we can hold onto a largestd::map<StyleSheetId, std::map<std::string, juce::var>>which maps a stylesheet ID to a map of key/value style props on the native side. -
StyleSheet.createfills a new entry in this map and returns to javascript a map of of the IDs we created to reference these things, so that subsequently writingstyles.containerin javascript evaluates to the right styleSheetID for lookup in that map. - Now, during a render pass, we only have to pass a single style property for each View, and inside
View::setPropertywe can lookup the corresponding stylesheet props and update the target view in bulk, then repaint once. - In the end, this will drastically reduce the number of props going over the native boundary during each render pass, drastically reduce the number of repaint() calls triggered, and help us cache previously painted views (if we see a new style property that matches the one I already have, no need to bulk update, no need to repaint).
I want to also mention here the discussion we had in #217: https://github.com/nick-thompson/blueprint/pull/217#discussion_r567448122. This discussion is about using props.getWithDefault on the native side. Generally I suspect we'll still lean on props.getWithDefault within our setProperty overrides because we always want to render something if we can. But with the atomic/bulk stylesheet updates we can more safely assume that during a styles update, all default style properties are indeed set by the time we care about them. Currently I'm not sure exactly how much that will change the way we write this type of code, but it's worth mentioning.