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.js"></script>
<script src="/js/react-dom.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="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/modal.jsx" type="text/babel"></script>
<script src="/js/sync-policy.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> <script src="/js/set-all-sync-policies.jsx" type="text/babel"></script>

View file

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