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 @@ ...@@ -44,6 +44,9 @@
"husky": "0.13.1", "husky": "0.13.1",
"lodash.bindall": "4.4.0", "lodash.bindall": "4.4.0",
"lodash.defaultsdeep": "4.6.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", "minilog": "3.1.0",
"opt-cli": "1.5.1", "opt-cli": "1.5.1",
"postcss-loader": "1.2.2", "postcss-loader": "1.2.2",
......
const isEqual = require('lodash.isequal');
const omit = require('lodash.omit');
const React = require('react'); const React = require('react');
const VM = require('scratch-vm'); const VM = require('scratch-vm');
...@@ -15,87 +17,98 @@ const StageSelector = require('../../containers/stage-selector.jsx'); ...@@ -15,87 +17,98 @@ const StageSelector = require('../../containers/stage-selector.jsx');
* @param {object} props Props for the component * @param {object} props Props for the component
* @returns {React.Component} rendered component * @returns {React.Component} rendered component
*/ */
const TargetPane = function (props) { class TargetPane extends React.Component {
const { shouldComponentUpdate (nextProps) {
editingTarget, return (
backdropLibraryVisible, // Do a normal shallow compare on all props except sprites
costumeLibraryVisible, Object.keys(omit(nextProps, ['sprites']))
spriteLibraryVisible, .reduce((all, k) => all || nextProps[k] !== this.props[k], false) ||
onNewSpriteClick, // Deep compare on sprites object
onNewCostumeClick, !isEqual(this.props.sprites, nextProps.sprites)
onNewBackdropClick, );
onRequestCloseBackdropLibrary, }
onRequestCloseCostumeLibrary, render () {
onRequestCloseSpriteLibrary, const {
onSelectSprite, editingTarget,
stage, backdropLibraryVisible,
sprites, costumeLibraryVisible,
vm, spriteLibraryVisible,
...componentProps onNewSpriteClick,
} = props; onNewCostumeClick,
return ( onNewBackdropClick,
<Box {...componentProps}> onRequestCloseBackdropLibrary,
<Box onRequestCloseCostumeLibrary,
alignContent="flex-start" onRequestCloseSpriteLibrary,
alignItems="flex-start" onSelectSprite,
grow={1} stage,
style={{overflowY: 'auto'}} sprites,
> vm,
<SpriteSelectorComponent ...componentProps
grow={1} } = this.props;
selectedId={editingTarget} return (
shrink={0} <Box {...componentProps}>
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 <Box
alignContent="flex-start" alignContent="flex-start"
alignItems="flex-start" alignItems="flex-start"
direction="column"
grow={1} grow={1}
shrink={0} style={{overflowY: 'auto'}}
> >
<button onClick={onNewSpriteClick}>New Sprite</button> <SpriteSelectorComponent
{editingTarget === stage.id ? ( grow={1}
<button onClick={onNewBackdropClick}>New Backdrop</button> selectedId={editingTarget}
) : ( shrink={0}
<button onClick={onNewCostumeClick}>New Costume</button> sprites={sprites}
)} width="100%"
<SpriteLibrary onSelectSprite={onSelectSprite}
visible={spriteLibraryVisible}
vm={vm}
onRequestClose={onRequestCloseSpriteLibrary}
/>
<CostumeLibrary
visible={costumeLibraryVisible}
vm={vm}
onRequestClose={onRequestCloseCostumeLibrary}
/>
<BackdropLibrary
visible={backdropLibraryVisible}
vm={vm}
onRequestClose={onRequestCloseBackdropLibrary}
/> />
</Box> </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>
</Box> );
); }
}; }
const spriteShape = React.PropTypes.shape({ const spriteShape = React.PropTypes.shape({
costume: React.PropTypes.shape({ costume: React.PropTypes.shape({
skin: React.PropTypes.string, skin: React.PropTypes.string,
......
const bindAll = require('lodash.bindall'); const bindAll = require('lodash.bindall');
const pick = require('lodash.pick');
const React = require('react'); const React = require('react');
const {connect} = require('react-redux'); const {connect} = require('react-redux');
...@@ -36,16 +37,19 @@ class TargetPane extends React.Component { ...@@ -36,16 +37,19 @@ class TargetPane extends React.Component {
const { const {
onSelectSprite, // eslint-disable-line no-unused-vars onSelectSprite, // eslint-disable-line no-unused-vars
...targetSelectorProps ...targetPaneProps
} = TargetPaneComponent.propTypes; } = TargetPaneComponent.propTypes;
TargetPane.propTypes = { TargetPane.propTypes = {
...targetSelectorProps ...targetPaneProps
}; };
const mapStateToProps = state => ({ const mapStateToProps = state => ({
editingTarget: state.targets.editingTarget, 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, stage: state.targets.stage,
spriteLibraryVisible: state.modals.spriteLibrary, spriteLibraryVisible: state.modals.spriteLibrary,
costumeLibraryVisible: state.modals.costumeLibrary, 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