DateTime: avoid unnecessary update (#6110)
## Issue Part of `5834 Performance investigation` In a homepage with 120 tiles, the lists get rendered 3 times during initial update. The sub-components are updating recursively (will investigate), so instead of 120 DateTime renders, we have 1000+ renders. The resolved DateTime string for `timeAgo` rarely changes, and even if the string was "a few seconds ago", there's no real need to constantly update it. ## Change Require a minimum 1-minute delta when deciding whether the component should update. Clients can change this value as needed. ## Test - [x] Verified `shouldComponentUpdate` doesn't end up taking more time than not having it (it's in micro-second range, compared to the millisecond render). - [x] Profiler showed no significant improvement for low number of DateTime components, but for the 120 DateTime case, almost 1/4 of a second is saved.
This commit is contained in:
parent
9e13596104
commit
cded632fd2
1 changed files with 49 additions and 3 deletions
|
@ -2,15 +2,29 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
|
const DEFAULT_MIN_UPDATE_DELTA_MS = 60 * 1000;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
date?: any,
|
date?: any,
|
||||||
timeAgo?: boolean,
|
timeAgo?: boolean,
|
||||||
formatOptions: {},
|
formatOptions?: {},
|
||||||
show?: string,
|
show?: string,
|
||||||
clock24h: boolean,
|
clock24h?: boolean,
|
||||||
|
minUpdateDeltaMs?: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DateTime extends React.PureComponent<Props> {
|
type State = {
|
||||||
|
lastRenderTime: Date,
|
||||||
|
};
|
||||||
|
|
||||||
|
class DateTime extends React.Component<Props, State> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
lastRenderTime: new Date(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static SHOW_DATE = 'date';
|
static SHOW_DATE = 'date';
|
||||||
static SHOW_TIME = 'time';
|
static SHOW_TIME = 'time';
|
||||||
|
|
||||||
|
@ -45,6 +59,38 @@ class DateTime extends React.PureComponent<Props> {
|
||||||
return __(strId, { duration });
|
return __(strId, { duration });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate(nextProps: Props): boolean {
|
||||||
|
if (
|
||||||
|
moment(this.props.date).diff(moment(nextProps.date)) !== 0 ||
|
||||||
|
this.props.clock24h !== nextProps.clock24h ||
|
||||||
|
this.props.timeAgo !== nextProps.timeAgo ||
|
||||||
|
this.props.minUpdateDeltaMs !== nextProps.minUpdateDeltaMs ||
|
||||||
|
this.props.show !== nextProps.show
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.timeAgo && nextProps.timeAgo) {
|
||||||
|
const minUpdateDeltaMs = this.props.minUpdateDeltaMs || DEFAULT_MIN_UPDATE_DELTA_MS;
|
||||||
|
const prev = moment(this.state.lastRenderTime);
|
||||||
|
const curr = moment(new Date());
|
||||||
|
const deltaMs = curr.diff(prev);
|
||||||
|
|
||||||
|
if (deltaMs > minUpdateDeltaMs) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
const { timeAgo } = this.props;
|
||||||
|
if (timeAgo) {
|
||||||
|
this.setState({ lastRenderTime: new Date() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { date, timeAgo, show, clock24h } = this.props;
|
const { date, timeAgo, show, clock24h } = this.props;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue