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

Themes: Avoid DOM reconciliation for existing themes on scroll #2915

Merged
merged 1 commit into from
Feb 1, 2016

Conversation

seear
Copy link
Contributor

@seear seear commented Jan 29, 2016

Before
screen shot 2016-01-29 at 12 12 08

After
screen shot 2016-01-29 at 12 02 11

These tables show time wasted reconciling component tree sections that have not changed. The start/stops have been placed around the fetchNextPage() call in the <themes-list-fetcher/>, like this:

        Perf.start();
        this.props.fetchNextPage( site );
        Perf.stop();
        let measurements = Perf.getLastMeasurements();
        Perf.printWasted( measurements );

This prints a table every time a scroll causes the next page of themes to be fetched and rendered. The tables above are towards the end of the entire set of themes.

The theme component was using the pure render mixin to avoid
reconciliation on re-render. Due to the complex nature of the
props, the reconciliation was never being short-circuited.

This PR Implements a custom shouldComponentUpdate method that does a deep
comparison on the theme object prop. We can see from the second table that no time is now wasted attempting to reconcile the huge amount of existing themes on the page.

To Test

  • Go to http://calypso.localhost:3000/design
  • Test theme scroll
  • Test theme activation and verify that he activated theme gets a blue border and changed button options of activation
  • Anything else that should update in the theme component?

The theme component was using the pure render mixin to avoid
reconciliation on re-render. Due to the complex nature of the
props, the reconciliation was never being short-circuited.

Implement a custom shouldComponentUpdate method that does a deep
comparison on the theme object prop.
@seear seear added [Feature Group] Appearance & Themes Features related to the appearance of sites. [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Jan 29, 2016
@seear seear self-assigned this Jan 29, 2016
@@ -62,6 +61,10 @@ var Theme = React.createClass( {
actionLabel: React.PropTypes.string
},

shouldComponentUpdate: function( nextProps ) {
return ! isEqual( nextProps.theme, this.props.theme );
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't comparing theme.id and theme.active be sufficient here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Shouldn't comparing theme.id and theme.active be sufficient here?

Yeah you are right there, but the fact that there may not be a theme obj supplied (in the placeholder usage case) pushed me to go for isEqual as the simpler, more readable approach. Make sense, or should we just compare the relevant fields since this is on the speed-critical path?

Copy link
Member

Choose a reason for hiding this comment

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

To prevent headaches later, it's better to compare the whole theme object — it shouldn't be horrendously slow.

@ehg
Copy link
Member

ehg commented Feb 1, 2016

Code looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature Group] Appearance & Themes Features related to the appearance of sites.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants