Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sqllab] optimizing React #1438

Merged
merged 2 commits into from
Oct 27, 2016
Merged

Conversation

mistercrunch
Copy link
Member

@mistercrunch mistercrunch commented Oct 26, 2016

@ascott @vera-liu @bkyryliuk
The UI is much more snappy after these changes. I noticed keystrokes in the editor were getting quite laggy, incrementally as the query history would grow or when the result set was large.

The big win is to not re-render the whole page at each keystroke in the AceEditor by wrapping it in its own component and managing local state there: affecting the store only onBlur events.

I also made pretty much every component a PureComponent which reduces the amount of rendering dramatically.

@ascott I'm doing this trick with shouldComponentUpdate to work around the fact that denormalizing the query array in the "controller"'s rendering method (to go from a global object in the store, to editor-specific array of queries) always creates a new array object. I made this function areArraysDifferent which looks inside the array for comparison. Any cleaner way to do this? It seems like it would be a common problem when denormalizing. Maybe keeping the array in the controller's state and handling the mutation there only if necessary?

@bkyryliuk
Copy link
Member

Looks good to me.

@@ -27,7 +27,7 @@ const defaultProps = {
};


class QueryTable extends React.Component {
class QueryTable extends React.PureComponent {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens when we extend PureComponent rather than Component and don't use componentShouldUpdate method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PureComponent implements its own shouldComponentUpdate that checks for shallow difference in this.state.* and this.props.* against the next values.

@@ -27,7 +27,7 @@ const defaultProps = {
};


class QueryTable extends React.Component {
class QueryTable extends React.PureComponent {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gotcha, thx

};

const defaultProps = {
sql: '',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since sql is required we don't need a default prop here

@@ -74,3 +74,22 @@ export function enhancer() {
}
return enhancerWithPersistState;
}

export function areArrayDifferent(arr1, arr2) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i might name this areArraysEqual rather than different. i think testing for equality is a little more clear/common pattern.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with different because it matches shouldComponentUpdate's bool. I can flip it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

going with areArraysShallowEqual

}
const length = arr1.length;
for (let i = 0; i < length; i++) {
if (arr1[i] !== arr2[i]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will the arrays to be compared ever be nested arrays?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new name areArraysShallowEqual makes it clear that this function doesn't recurse

editorProps={{ $blockScrolling: true }}
enableBasicAutocompletion
value={this.props.queryEditor.sql}
<AceEditorWrapper
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's common in react to use container rather than wrapper, but nbd.

textChange(text) {
this.setState({ sql: text });
this.props.actions.queryEditorSetSql(this.props.queryEditor, text);
sqlToStore(sql) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this be called setQueryEditorSql for clarity?

@ascott
Copy link
Contributor

ascott commented Oct 26, 2016

+1 to performance improvements!

@mistercrunch
Copy link
Member Author

Addressed all comments, mergin'!

@mistercrunch mistercrunch merged commit b242063 into apache:master Oct 27, 2016
@mistercrunch mistercrunch deleted the optimiz_sqllab branch October 27, 2016 00:41
@ascott
Copy link
Contributor

ascott commented Oct 27, 2016

💯

zhaoyongjie pushed a commit to zhaoyongjie/incubator-superset that referenced this pull request Nov 17, 2021
* Update controlPanel.tsx

* Update index.tsx

* Update dndControls.tsx
zhaoyongjie pushed a commit to zhaoyongjie/incubator-superset that referenced this pull request Nov 24, 2021
* Update controlPanel.tsx

* Update index.tsx

* Update dndControls.tsx
zhaoyongjie pushed a commit to zhaoyongjie/incubator-superset that referenced this pull request Nov 25, 2021
* Update controlPanel.tsx

* Update index.tsx

* Update dndControls.tsx
zhaoyongjie pushed a commit to zhaoyongjie/incubator-superset that referenced this pull request Nov 26, 2021
* Update controlPanel.tsx

* Update index.tsx

* Update dndControls.tsx
@mistercrunch mistercrunch added 🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 0.12.0 labels Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 0.12.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants