mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-10 17:23:42 +08:00
Improve Header performance a bit (#3556)
* Improve `Header` performance a bit I have been investigating `<Header />` component performance once again today with `render` cycles in particular. I have observed that during `push` phase, a typical Header in NavigationPlayground re-renders 3 times on iOS and 2 times on Android. The first time is obvious on both platforms since that's when we add a new scene to an array. Second on iOS was also self-explanatory - we measure title width and other layout parameters in order to provide a better animation. What got me thinking was the last render cycle that didn't have a clear origin. After digging around I've found it is caused by a `scenes` array changing when transition finishes. What is surprising, it's just the reference to the object that changes, the content (items inside) stay the same. I have found out that this is caused by `Transitioner` looping through an array of scenes attempting to remove stale scenes. Since scene becomes stale when you `pop` from it, this is obviously a noop when `pushing` a new route. That, obviously, causes an extra render cycle since `filter` produces same, but with a different pointer, object. * Update Transitioner.js * Update Transitioner.js
This commit is contained in:
@@ -179,9 +179,19 @@ class Transitioner extends React.Component {
|
||||
const prevTransitionProps = this._prevTransitionProps;
|
||||
this._prevTransitionProps = null;
|
||||
|
||||
const scenes = this.state.scenes.filter(isSceneNotStale);
|
||||
|
||||
const nextState = {
|
||||
...this.state,
|
||||
scenes: this.state.scenes.filter(isSceneNotStale),
|
||||
/**
|
||||
* Array.prototype.filter creates a new instance of an array
|
||||
* even if there were no elements removed. There are cases when
|
||||
* `this.state.scenes` will have no stale scenes (typically when
|
||||
* pushing a new route). As a result, components that rely on this prop
|
||||
* might enter an unnecessary render cycle.
|
||||
*/
|
||||
scenes:
|
||||
this.state.scenes.length === scenes.length ? this.state.scenes : scenes,
|
||||
};
|
||||
|
||||
this._transitionProps = buildTransitionProps(this.props, nextState);
|
||||
|
||||
Reference in New Issue
Block a user