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

Desktop: Performance: suppresses redundant SideBar re-rendering on state.tags #6451

Merged
merged 3 commits into from
Jun 8, 2022

Conversation

ken1kob
Copy link
Contributor

@ken1kob ken1kob commented Apr 24, 2022

This PR is one of PRs resolving issue #6386 and improves UI responses.

Problem

When a notebook is changed using Sidebar, re-rendering of Sidebar happens three times as the Performance Analyzer view (A) in the below image.

pa-compare-state-tabs

In this case, data used for Sidebar don't change so many times, and the number of the times of re-rendering should be less.

Cause and Treatment

The cause of re-rendering is as follows.

  1. TAG_UPDATE_ALL action is performed several times, when Sidebar's notebook is clicked.
  2. For each time, state.tags changes even if the content of the tag list does not change. Their semantic values are the same, but their object references differ.
  3. Sidebar is re-rendered for each change of state.tags.

To fix the problem, state.tags should not be changed when a given new content of the tag list is the same.

Result

After this PR is applied, as the view (B) in the above image, two Re-renderings of Sidebar are reduced from the above Performance Analyzer image. The total reduction time is 186 msec.

draft.tags = action.items;
if (!isDeepStrictEqual(original(draft.tags), action.items)) {
draft.tags = action.items;
}
Copy link
Owner

Choose a reason for hiding this comment

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

It's strange that we'd need that because the point of immer is that it already performs this check for us. Otherwise we'd need to have everywhere if (value !== previousValue) draf.value = value but of course we don't (and if needed that, we may as well remove the immer dependency since it would no longer be useful).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not strange. Immer will find changes according to reference equality, but it doesn't check the deep equality of the found changes.

if (value !== previousValue) draf.value = value is not needed, because it checks reference equality which is performed by Immer.

Copy link
Owner

@laurent22 laurent22 Apr 29, 2022

Choose a reason for hiding this comment

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

Right, that's correct, I was confused.

This reducer is also used in the mobile app and I don't think React Native has this "utils" module. We have "fastDeepEqual" which I think you can use instead.

By the way, I guess it should be easy to unit test this? You just do state = reducer(state, action); and compare the state before and after.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This reducer is also used in the mobile app and I don't think React Native has this "utils" module.

Sorry, I wasn't aware of the point.

Finished. d1e7816

nodes.js/util/isDeepStrictEqual() -> fastDeepEqual()
@laurent22
Copy link
Owner

There's conflict on the reducer file, please could you fix it? Once it's done we can merge

@ken1kob
Copy link
Contributor Author

ken1kob commented Jun 7, 2022

Done.

@laurent22 laurent22 merged commit c320d23 into laurent22:dev Jun 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants