Skip to content

Commit 128ecd4

Browse files
emizzleiurimatias
authored andcommitted
fix(@embark/core): Prevent unnecessary re-renderings
The services websocket was initiated in the AppContainer and causing all child components to continuously re-render every time there was a service check (which is effectively every second). In addition, the socket was never stopped when not needed (ie when the services component was unmounted). Create a ServicesContainer that initiates the websocket as part of the container, and stops the socket when the container is unmounted. Move the ContractsList to be part of the ContractsContainer with a `mode` switch. Add Deployment page title and description.
1 parent cc495c5 commit 128ecd4

File tree

8 files changed

+138
-47
lines changed

8 files changed

+138
-47
lines changed

packages/embark-ui/src/actions/index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,11 +447,13 @@ export const WATCH_SERVICES = 'WATCH_SERVICES';
447447
export const WATCH_NEW_CONTRACT_LOGS = 'WATCH_NEW_CONTRACT_LOGS';
448448
export const WATCH_NEW_CONTRACT_EVENTS = 'WATCH_NEW_CONTRACT_EVENTS';
449449
export const WATCH_CONTRACTS = 'WATCH_CONTRACTS';
450+
export const STOP_CONTRACTS = 'STOP_CONTRACTS';
450451
export const INIT_BLOCK_HEADER = 'INIT_BLOCK_HEADER';
451452
export const STOP_BLOCK_HEADER = 'STOP_BLOCK_HEADER';
452453
export const WATCH_GAS_ORACLE = 'WATCH_GAS_ORACLE';
453454
export const STOP_GAS_ORACLE = 'STOP_GAS_ORACLE';
454455
export const STOP_DEBUGGER = 'STOP_DEBUGGER';
456+
export const STOP_SERVICES = 'STOP_SERVICES';
455457

456458
export function listenToProcessLogs(processName) {
457459
return {
@@ -509,12 +511,24 @@ export function listenToContracts(){
509511
};
510512
}
511513

514+
export function stopContracts(){
515+
return {
516+
type: STOP_CONTRACTS
517+
};
518+
}
519+
512520
export function stopGasOracle(){
513521
return {
514522
type: STOP_GAS_ORACLE
515523
};
516524
}
517525

526+
export function stopServices(){
527+
return {
528+
type: STOP_SERVICES
529+
};
530+
}
531+
518532
export function stopDebugger(){
519533
return {
520534
type: STOP_DEBUGGER

packages/embark-ui/src/components/Processes.js renamed to packages/embark-ui/src/components/Services.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,26 @@ function iconClasses(state){
1818
});
1919
}
2020

21-
const Process = ({process}) => (
21+
const Service = ({service}) => (
2222
<Col xs={12} sm={6} md={4} xl={3}>
23-
<Widget02 header={process.name} mainText={process.description} icon={iconClasses(process.state)} color={colorClasses(process.state)} variant="1" />
23+
<Widget02 header={service.name} mainText={service.description} icon={iconClasses(service.state)} color={colorClasses(service.state)} variant="1" />
2424
</Col>
2525
);
2626

27-
Process.propTypes = {
28-
process: PropTypes.object
27+
Service.propTypes = {
28+
service: PropTypes.object
2929
};
3030

31-
const Processes = ({processes}) => (
31+
const Services = ({services}) => (
3232
<Row>
33-
{processes
33+
{services
3434
.sort((a, b) => a.name < b.name ? 1 : 0)
35-
.map((process) => <Process key={process.name} process={process} />)}
35+
.map((service) => <Service key={service.name} service={service} />)}
3636
</Row>
3737
);
3838

39-
Processes.propTypes = {
40-
processes: PropTypes.arrayOf(PropTypes.object)
39+
Services.propTypes = {
40+
services: PropTypes.arrayOf(PropTypes.object)
4141
};
4242

43-
export default Processes;
43+
export default Services;

packages/embark-ui/src/containers/AppContainer.js

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import {
1414
processes as processesAction,
1515
versions as versionsAction,
1616
plugins as pluginsAction,
17-
listenToServices as listenToServicesAction,
18-
listenToContracts as listenToContractsAction,
1917
initRegularTxs as initRegularTxsAction,
2018
stopRegularTxs as stopRegularTxsAction,
2119
changeTheme, fetchTheme
@@ -81,11 +79,8 @@ class AppContainer extends Component {
8179
}
8280

8381
if (this.props.credentials.authenticated && !this.props.initialized) {
84-
this.props.fetchProcesses();
85-
this.props.fetchServices();
86-
this.props.listenToServices();
8782
this.props.fetchPlugins();
88-
this.props.listenToContracts();
83+
this.props.fetchProcesses();
8984
if (enableRegularTxs === "true") {
9085
this.props.initRegularTxs();
9186
this.props.history.replace(stripQueryParam(this.props.location, ENABLE_REGULAR_TXS));
@@ -150,18 +145,14 @@ AppContainer.propTypes = {
150145
authenticate: PropTypes.func,
151146
logout: PropTypes.func,
152147
fetchCredentials: PropTypes.func,
153-
initBlockHeader: PropTypes.func,
154148
fetchProcesses: PropTypes.func,
155-
fetchServices: PropTypes.func,
156149
fetchPlugins: PropTypes.func,
157150
fetchVersions: PropTypes.func,
158151
location: PropTypes.object,
159152
theme: PropTypes.string,
160153
changeTheme: PropTypes.func,
161154
fetchTheme: PropTypes.func,
162155
history: PropTypes.object,
163-
listenToServices: PropTypes.func,
164-
listenToContracts: PropTypes.func,
165156
initRegularTxs: PropTypes.func,
166157
stopRegularTxs: PropTypes.func
167158
};
@@ -182,13 +173,10 @@ export default withRouter(connect(
182173
logout: logout.request,
183174
fetchCredentials: fetchCredentials.request,
184175
fetchProcesses: processesAction.request,
185-
fetchServices: processesAction.request,
186-
listenToServices: listenToServicesAction,
187176
fetchVersions: versionsAction.request,
188177
fetchPlugins: pluginsAction.request,
189178
changeTheme: changeTheme.request,
190179
fetchTheme: fetchTheme.request,
191-
listenToContracts: listenToContractsAction,
192180
initRegularTxs: initRegularTxsAction.request,
193181
stopRegularTxs: stopRegularTxsAction.request
194182
},
Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,36 @@
11
import React, {Component} from 'react';
22
import {connect} from 'react-redux';
33
import PropTypes from 'prop-types';
4-
import {contracts as contractsAction} from "../actions";
4+
import {
5+
listenToContracts as listenToContractsAction,
6+
stopContracts as stopContractsAction,
7+
contracts as contractsAction
8+
} from "../actions";
59

610
import Contracts from '../components/Contracts';
11+
import ContractsList from '../components/ContractsList';
712
import DataWrapper from "../components/DataWrapper";
813
import PageHead from "../components/PageHead";
914
import {getContracts} from "../reducers/selectors";
1015

1116
class ContractsContainer extends Component {
1217
componentDidMount() {
1318
this.props.fetchContracts();
19+
this.props.listenToContracts();
20+
}
21+
22+
componentWillUnmount() {
23+
this.props.stopContracts();
1424
}
1525

1626
render() {
1727
return (
1828
<React.Fragment>
19-
<PageHead title="Contracts" description="Summary of all deployed contracts" />
20-
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={({contracts}) => (
21-
<Contracts contracts={contracts} />
22-
)} />
29+
{this.props.updatePageHeader && <PageHead title="Contracts" description="Summary of all deployed contracts" />}
30+
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={({contracts}) => {
31+
if (this.props.mode === "list") return <ContractsList contracts={contracts} />;
32+
if (this.props.mode === "detail") return <Contracts contracts={contracts} />;
33+
}} />
2334
</React.Fragment>
2435
);
2536
}
@@ -33,13 +44,24 @@ function mapStateToProps(state) {
3344
}
3445

3546
ContractsContainer.propTypes = {
47+
listenToContracts: PropTypes.func,
48+
stopContracts: PropTypes.func,
3649
contracts: PropTypes.array,
3750
fiddleContracts: PropTypes.array,
38-
fetchContracts: PropTypes.func
51+
fetchContracts: PropTypes.func,
52+
mode: PropTypes.string,
53+
updatePageHeader: PropTypes.bool
3954
};
4055

56+
ContractsContainer.defaultProps = {
57+
mode: "detail",
58+
updatePageHeader: true
59+
}
60+
4161
export default connect(
4262
mapStateToProps,{
63+
listenToContracts: listenToContractsAction,
64+
stopContracts: stopContractsAction,
4365
fetchContracts: contractsAction.request
4466
}
4567
)(ContractsContainer);

packages/embark-ui/src/containers/DeploymentContainer.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99

1010
import ContractsDeployment from '../components/ContractsDeployment';
1111
import DataWrapper from "../components/DataWrapper";
12+
import PageHead from '../components/PageHead';
1213
import {getContracts, getDeploymentPipeline, getWeb3, getWeb3GasEstimates, getWeb3Deployments} from "../reducers/selectors";
1314

1415
class DeploymentContainer extends Component {
@@ -18,16 +19,19 @@ class DeploymentContainer extends Component {
1819

1920
render() {
2021
return (
21-
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={() => (
22-
<ContractsDeployment contracts={this.props.contracts}
23-
deploymentPipeline={this.props.deploymentPipeline}
24-
web3={this.props.web3}
25-
web3Deploy={this.props.web3Deploy}
26-
web3EstimateGas={this.props.web3EstimateGas}
27-
web3Deployments={this.props.web3Deployments}
28-
web3GasEstimates={this.props.web3GasEstimates}
29-
updateDeploymentPipeline={this.props.updateDeploymentPipeline} />
30-
)} />
22+
<React.Fragment>
23+
<PageHead title="Deployment" description="Deploy your contracts using Embark or a web3-enabled browser such as Mist or MetaMask." />
24+
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={() => (
25+
<ContractsDeployment contracts={this.props.contracts}
26+
deploymentPipeline={this.props.deploymentPipeline}
27+
web3={this.props.web3}
28+
web3Deploy={this.props.web3Deploy}
29+
web3EstimateGas={this.props.web3EstimateGas}
30+
web3Deployments={this.props.web3Deployments}
31+
web3GasEstimates={this.props.web3GasEstimates}
32+
updateDeploymentPipeline={this.props.updateDeploymentPipeline} />
33+
)} />
34+
</React.Fragment>
3135
);
3236
}
3337
}

packages/embark-ui/src/containers/HomeContainer.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ import {
1818
} from "../actions";
1919

2020
import DataWrapper from "../components/DataWrapper";
21-
import Processes from '../components/Processes';
2221
import Console from '../components/Console';
2322
import {EMBARK_PROCESS_NAME, LOG_LIMIT} from '../constants';
24-
import ContractsList from '../components/ContractsList';
2523
import PageHead from '../components/PageHead';
24+
import ServicesContainer from './ServicesContainer';
2625
import {getContracts, getProcesses, getProcessLogs, getServices, getCommandSuggestions} from "../reducers/selectors";
26+
import ContractsContainer from "./ContractsContainer";
2727

2828
class HomeContainer extends Component {
2929
constructor(props) {
@@ -53,9 +53,7 @@ class HomeContainer extends Component {
5353
return (
5454
<React.Fragment>
5555
<PageHead title="Dashboard" description="Overview of available services and logs. Interact with Embark using the console. Summary of deployed contracts." />
56-
<DataWrapper shouldRender={this.props.services.length > 0 } {...this.props} render={({services}) => (
57-
<Processes processes={services} />
58-
)} />
56+
<ServicesContainer />
5957

6058
<DataWrapper shouldRender={this.props.processes.length > 0 } {...this.props} render={({processes, postCommand, postCommandSuggestions, processLogs, commandSuggestions}) => (
6159
<Card>
@@ -78,7 +76,7 @@ class HomeContainer extends Component {
7876
<CardBody>
7977
<CardTitle>Deployed Contracts</CardTitle>
8078
<div style={{marginBottom: '1.5rem', overflow: 'auto'}}>
81-
<ContractsList contracts={contracts} />
79+
<ContractsContainer contracts={contracts} mode="list" updatePageHeader={false} />
8280
</div>
8381
</CardBody>
8482
</Card>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import PropTypes from "prop-types";
2+
import React, {Component} from 'react';
3+
import {connect} from 'react-redux';
4+
import Services from '../components/Services';
5+
import {
6+
listenToServices as listenToServicesAction,
7+
services as servicesAction,
8+
stopServices as stopServicesAction
9+
} from "../actions";
10+
import DataWrapper from "../components/DataWrapper";
11+
import {getServices} from "../reducers/selectors";
12+
13+
class ServicesContainer extends Component {
14+
componentDidMount() {
15+
this.props.fetchServices();
16+
this.props.listenToServices();
17+
}
18+
19+
componentWillUnmount() {
20+
this.props.stopServices();
21+
}
22+
23+
render() {
24+
return <DataWrapper shouldRender={this.props.services.length > 0 } {...this.props} render={({services}) => (
25+
<Services services={services} />
26+
)} />;
27+
28+
}
29+
}
30+
31+
ServicesContainer.propTypes = {
32+
fetchServices: PropTypes.func,
33+
listenToServices: PropTypes.func,
34+
};
35+
36+
function mapStateToProps(state, _props) {
37+
return {
38+
services: getServices(state)
39+
};
40+
}
41+
42+
export default connect(
43+
mapStateToProps,
44+
{
45+
fetchServices: servicesAction.request,
46+
listenToServices: listenToServicesAction,
47+
stopServices: stopServicesAction
48+
}
49+
)(ServicesContainer);

packages/embark-ui/src/sagas/index.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,15 @@ export function *listenServices() {
420420
const socket = api.webSocketServices(credentials);
421421
const channel = yield call(createChannel, socket);
422422
while (true) {
423-
const services = yield take(channel);
423+
const { cancel, services } = yield race({
424+
services: take(channel),
425+
cancel: take(actions.STOP_SERVICES)
426+
});
427+
428+
if (cancel) {
429+
channel.close();
430+
return;
431+
}
424432
yield put(actions.services.success(services));
425433
}
426434
}
@@ -506,7 +514,15 @@ export function *listenContracts() {
506514
const socket = api.webSocketContracts(credentials);
507515
const channel = yield call(createChannel, socket);
508516
while (true) {
509-
const contracts = yield take(channel);
517+
const { cancel, contracts } = yield race({
518+
contracts: take(channel),
519+
cancel: take(actions.STOP_CONTRACTS)
520+
});
521+
522+
if (cancel) {
523+
channel.close();
524+
return;
525+
}
510526
yield put(actions.contracts.success(contracts));
511527
}
512528
}

0 commit comments

Comments
 (0)