Reduce extra rendering in NavigationCard

Summary: This adds a new SceneView with a shouldComponentUpdate policy of only re-rendering when the scene's state changes. This allows avoidance of extra re-renders. Results in a much smoother back-swipe gesture because we no longer re-render scenes as we transition from gesture to animation.

Reviewed By: hedgerwang

Differential Revision: D3219545

fb-gh-sync-id: 7c04e0e4ebb40d1e57ef7af11e2e54adf4f52aa0
fbshipit-source-id: 7c04e0e4ebb40d1e57ef7af11e2e54adf4f52aa0
This commit is contained in:
Eric Vicenti
2016-05-03 13:30:24 -07:00
committed by Facebook Github Bot 2
parent 20d53b1f23
commit bb39a2e9da
2 changed files with 46 additions and 17 deletions

View File

@@ -51,6 +51,11 @@ import type {
NavigationSceneRendererProps,
} from 'NavigationTypeDefinition';
type SceneViewProps = {
sceneRenderer: NavigationSceneRenderer,
sceneRendererProps: NavigationSceneRendererProps,
};
type Props = NavigationSceneRendererProps & {
onComponentRef: (ref: any) => void,
panHandlers: ?NavigationPanPanHandlers,
@@ -61,6 +66,25 @@ type Props = NavigationSceneRendererProps & {
const {PropTypes} = React;
class SceneView extends React.Component<any, SceneViewProps, any> {
static propTypes = {
sceneRenderer: PropTypes.func.isRequired,
sceneRendererProps: NavigationPropTypes.SceneRenderer,
};
shouldComponentUpdate(nextProps: SceneViewProps, nextState: any): boolean {
return (
nextProps.sceneRendererProps.scene.navigationState !==
this.props.sceneRendererProps.scene.navigationState
);
}
render(): ?ReactElement {
return this.props.sceneRenderer(this.props.sceneRendererProps);
}
}
/**
* Component that renders the scene as card for the <NavigationCardStack />.
*/
@@ -107,7 +131,10 @@ class NavigationCard extends React.Component<any, Props, any> {
pointerEvents={pointerEvents}
ref={this.props.onComponentRef}
style={[styles.main, viewStyle]}>
{renderScene(props)}
<SceneView
sceneRenderer={renderScene}
sceneRendererProps={props}
/>
</Animated.View>
);
}