Optimize dashboard rendering

Add version to local copy of account and only re-render entire account
if the version is different. Create an ElapsedTime component that
re-renders on its own, and update SyncGraph to re-render on its
own as well.
This commit is contained in:
Halla Moore 2016-07-13 14:34:03 -07:00
parent a5e3ddb445
commit b03b8b537d
4 changed files with 62 additions and 3 deletions

View file

@ -3,6 +3,7 @@
<script src="/js/react.js"></script>
<script src="/js/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="/js/elapsed-time.jsx" type="text/babel"></script>
<script src="/js/modal.jsx" type="text/babel"></script>
<script src="/js/sync-policy.jsx" type="text/babel"></script>
<script src="/js/set-all-sync-policies.jsx" type="text/babel"></script>

View file

@ -9,6 +9,7 @@ const {
AccountFilter,
SyncGraph,
SyncbackRequestDetails,
ElapsedTime,
} = window;
function calcAcctPosition(count) {
@ -26,13 +27,23 @@ function calcAcctPosition(count) {
return {left: left, top: top};
}
function formatSyncTimes(timestamp) {
return timestamp / 1000;
}
class Account extends React.Component {
constructor(props) {
super(props);
this.state = {
accountId: props.account.id,
version: null,
}
}
shouldComponentUpdate(nextProps) {
return nextProps.account.version !== this.props.account.version;
}
clearError() {
const req = new XMLHttpRequest();
const url = `${window.location.protocol}/accounts/${this.state.accountId}/clear-sync-error`;
@ -48,6 +59,7 @@ class Account extends React.Component {
}
req.send();
}
renderError() {
const {account} = this.props;
@ -80,7 +92,6 @@ class Account extends React.Component {
const oldestSync = account.last_sync_completions[numStoredSyncs - 1];
const newestSync = account.last_sync_completions[0];
const avgBetweenSyncs = (newestSync - oldestSync) / (1000 * numStoredSyncs);
const timeSinceLastSync = (Date.now() - newestSync) / 1000;
let firstSyncDuration = "Incomplete";
if (account.first_sync_completion) {
@ -108,7 +119,9 @@ class Account extends React.Component {
<b> Average Time Between Syncs (seconds)</b>:
<pre>{avgBetweenSyncs}</pre>
<b>Time Since Last Sync (seconds)</b>:
<pre>{timeSinceLastSync}</pre>
<pre>
<ElapsedTime refTimestamp={newestSync} formatTime={formatSyncTimes} />
</pre>
<b>Recent Syncs</b>:
<SyncGraph id={account.last_sync_completions.length} syncTimestamps={account.last_sync_completions} />
</div>
@ -166,6 +179,11 @@ class Root extends React.Component {
onReceivedUpdate(update) {
const accounts = Object.assign({}, this.state.accounts);
for (const account of update.updatedAccounts) {
if (accounts[account.id]) {
account.version = accounts[account.id].version + 1;
} else {
account.version = 0;
}
accounts[account.id] = account;
}

View file

@ -0,0 +1,31 @@
const React = window.React;
class ElapsedTime extends React.Component {
constructor(props) {
super(props);
this.state = {
elapsed: 0,
}
}
componentDidMount() {
this.interval = setInterval(() => {
this.setState({elapsed: Date.now() - this.props.refTimestamp})
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <span>{this.props.formatTime(this.state.elapsed)} </span>
}
}
ElapsedTime.propTypes = {
refTimestamp: React.PropTypes.number, // milliseconds
formatTime: React.PropTypes.func,
}
window.ElapsedTime = ElapsedTime;

View file

@ -2,15 +2,24 @@ const React = window.React;
const ReactDOM = window.ReactDOM;
class SyncGraph extends React.Component {
componentDidMount() {
this.drawGraph(true);
this.interval = setInterval(() => {
if (Date.now() - this.props.syncTimestamps[0] > 10000) {
this.drawGraph(false);
}
}, 10000);
}
componentDidUpdate() {
this.drawGraph(false);
}
componentWillUnmount() {
clearInterval(this.interval);
}
drawGraph(isInitial) {
const now = Date.now();
const config = SyncGraph.config;