Skip to content
Snippets Groups Projects
Commit bd648e3b authored by Ray Schamp's avatar Ray Schamp
Browse files

Implement shouldComponentUpdate on TargetPane

Improves performance by comparing sprite info values (rather than object identities), and by excluding irrelevant data from this comparison.
parent 0941ed01
No related branches found
No related tags found
No related merge requests found
......@@ -44,6 +44,9 @@
"husky": "0.13.1",
"lodash.bindall": "4.4.0",
"lodash.defaultsdeep": "4.6.0",
"lodash.isequal": "4.5.0",
"lodash.omit": "4.5.0",
"lodash.pick": "4.4.0",
"minilog": "3.1.0",
"opt-cli": "1.5.1",
"postcss-loader": "1.2.2",
......
const isEqual = require('lodash.isequal');
const omit = require('lodash.omit');
const React = require('react');
const VM = require('scratch-vm');
......@@ -15,87 +17,98 @@ const StageSelector = require('../../containers/stage-selector.jsx');
* @param {object} props Props for the component
* @returns {React.Component} rendered component
*/
const TargetPane = function (props) {
const {
editingTarget,
backdropLibraryVisible,
costumeLibraryVisible,
spriteLibraryVisible,
onNewSpriteClick,
onNewCostumeClick,
onNewBackdropClick,
onRequestCloseBackdropLibrary,
onRequestCloseCostumeLibrary,
onRequestCloseSpriteLibrary,
onSelectSprite,
stage,
sprites,
vm,
...componentProps
} = props;
return (
<Box {...componentProps}>
<Box
alignContent="flex-start"
alignItems="flex-start"
grow={1}
style={{overflowY: 'auto'}}
>
<SpriteSelectorComponent
grow={1}
selectedId={editingTarget}
shrink={0}
sprites={sprites}
width="100%"
onSelectSprite={onSelectSprite}
/>
</Box>
<Box
direction="column"
shrink={0}
width={72}
>
{stage.id && <StageSelector
backdropCount={stage.costumeCount}
id={stage.id}
selected={stage.id === editingTarget}
shrink={0}
url={stage.costume.skin}
onSelect={onSelectSprite}
/>}
class TargetPane extends React.Component {
shouldComponentUpdate (nextProps) {
return (
// Do a normal shallow compare on all props except sprites
Object.keys(omit(nextProps, ['sprites']))
.reduce((all, k) => all || nextProps[k] !== this.props[k], false) ||
// Deep compare on sprites object
!isEqual(this.props.sprites, nextProps.sprites)
);
}
render () {
const {
editingTarget,
backdropLibraryVisible,
costumeLibraryVisible,
spriteLibraryVisible,
onNewSpriteClick,
onNewCostumeClick,
onNewBackdropClick,
onRequestCloseBackdropLibrary,
onRequestCloseCostumeLibrary,
onRequestCloseSpriteLibrary,
onSelectSprite,
stage,
sprites,
vm,
...componentProps
} = this.props;
return (
<Box {...componentProps}>
<Box
alignContent="flex-start"
alignItems="flex-start"
direction="column"
grow={1}
shrink={0}
style={{overflowY: 'auto'}}
>
<button onClick={onNewSpriteClick}>New Sprite</button>
{editingTarget === stage.id ? (
<button onClick={onNewBackdropClick}>New Backdrop</button>
) : (
<button onClick={onNewCostumeClick}>New Costume</button>
)}
<SpriteLibrary
visible={spriteLibraryVisible}
vm={vm}
onRequestClose={onRequestCloseSpriteLibrary}
/>
<CostumeLibrary
visible={costumeLibraryVisible}
vm={vm}
onRequestClose={onRequestCloseCostumeLibrary}
/>
<BackdropLibrary
visible={backdropLibraryVisible}
vm={vm}
onRequestClose={onRequestCloseBackdropLibrary}
<SpriteSelectorComponent
grow={1}
selectedId={editingTarget}
shrink={0}
sprites={sprites}
width="100%"
onSelectSprite={onSelectSprite}
/>
</Box>
<Box
direction="column"
shrink={0}
width={72}
>
{stage.id && <StageSelector
backdropCount={stage.costumeCount}
id={stage.id}
selected={stage.id === editingTarget}
shrink={0}
url={stage.costume.skin}
onSelect={onSelectSprite}
/>}
<Box
alignContent="flex-start"
alignItems="flex-start"
direction="column"
grow={1}
shrink={0}
>
<button onClick={onNewSpriteClick}>New Sprite</button>
{editingTarget === stage.id ? (
<button onClick={onNewBackdropClick}>New Backdrop</button>
) : (
<button onClick={onNewCostumeClick}>New Costume</button>
)}
<SpriteLibrary
visible={spriteLibraryVisible}
vm={vm}
onRequestClose={onRequestCloseSpriteLibrary}
/>
<CostumeLibrary
visible={costumeLibraryVisible}
vm={vm}
onRequestClose={onRequestCloseCostumeLibrary}
/>
<BackdropLibrary
visible={backdropLibraryVisible}
vm={vm}
onRequestClose={onRequestCloseBackdropLibrary}
/>
</Box>
</Box>
</Box>
</Box>
);
};
);
}
}
const spriteShape = React.PropTypes.shape({
costume: React.PropTypes.shape({
skin: React.PropTypes.string,
......
const bindAll = require('lodash.bindall');
const pick = require('lodash.pick');
const React = require('react');
const {connect} = require('react-redux');
......@@ -36,16 +37,19 @@ class TargetPane extends React.Component {
const {
onSelectSprite, // eslint-disable-line no-unused-vars
...targetSelectorProps
...targetPaneProps
} = TargetPaneComponent.propTypes;
TargetPane.propTypes = {
...targetSelectorProps
...targetPaneProps
};
const mapStateToProps = state => ({
editingTarget: state.targets.editingTarget,
sprites: state.targets.sprites,
sprites: Object.keys(state.targets.sprites).reduce((sprites, k) => {
sprites[k] = pick(state.targets.sprites[k], ['costume', 'name', 'order']);
return sprites;
}, {}),
stage: state.targets.stage,
spriteLibraryVisible: state.modals.spriteLibrary,
costumeLibraryVisible: state.modals.costumeLibrary,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment