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

Fix unnecessary rerendering of side content in mobile workspace #2338

Merged

Conversation

ianyong
Copy link
Member

@ianyong ianyong commented Feb 1, 2023

Description

Played whack-a-mole with the React profiler until everything that is causing unnecessary re-rending of the side content tabs in the mobile view is memoized in some form or another. Note that unnecessary re-rendering here is only in the context of typing in the editor. The side content in the mobile view will definitely still re-render more than is necessary (i.e., more than the desktop view) by virtue of the React component hierarchy described in the paragraph below.

The main difficulty encountered here is that in the desktop workspace, the control bar is not nested in the side content component. As such, both of these components can re-render separately. In the mobile workspace however, the control bar is a child of the side content component. Whenever the control bar has to re-render, so does the side content. An alternative to all of these memoization would be to redesign the mobile workspace such that the control bar is not nested inside the side content component. This would also help prevent future changes from reintroducing this unnecessary re-render issue. However, this is also not an easy refactor to carry out.

Also implements @RichDom2185's suggestion to memoize components when exporting as default.

See each individual commit for the context behind every change.

Fixes #2332. Related to #2331.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Code quality improvements

How to test

Replicate the steps in the linked issue.

@@ -512,16 +549,23 @@ const Playground: React.FC<PlaygroundProps> = ({ workspaceLocation = 'playground

const { handleEditorValueChange } = props;

// No point memoing this, it uses props.editorValue
Copy link
Member Author

Choose a reason for hiding this comment

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

This turned out to be untrue...

Comment on lines 552 to 555
const getEditorValue = React.useCallback(
() => store.getState().workspaces.playground.editorTabs[0].value,
[store]
);
Copy link
Member Author

@ianyong ianyong Feb 1, 2023

Choose a reason for hiding this comment

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

We do this so that we only access the editor value when the session button is pressed, instead of constantly re-rendering the session button whenever the editor value changes. As a result, we need the store object which we retrieve using the useStore hook. This hook does not listen to changes (as compared to the useSelector hook which does and will force re-renders every time the listened value updates).

@coveralls
Copy link

coveralls commented Feb 1, 2023

Pull Request Test Coverage Report for Build 4090243912

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 5 of 48 (10.42%) changed or added relevant lines in 5 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.02%) to 34.449%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/commons/controlBar/ControlBarSessionButton.tsx 0 1 0.0%
src/commons/mobileWorkspace/mobileSideContent/MobileSideContent.tsx 1 11 9.09%
src/commons/mobileWorkspace/MobileWorkspace.tsx 0 16 0.0%
src/pages/playground/Playground.tsx 0 16 0.0%
Totals Coverage Status
Change from base Build 4090240661: -0.02%
Covered Lines: 4542
Relevant Lines: 12258

💛 - Coveralls

Copy link
Member

@RichDom2185 RichDom2185 left a comment

Choose a reason for hiding this comment

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

Just a minor comment; otherwise looks good, thanks for working on this!

Currently, the 'Playground' component is also used by the SICP workspace.

Co-authored-by: Richard Dominick <[email protected]>
@ianyong ianyong force-pushed the fix-unnecessary-rerendering-of-mobile-side-content branch from 5386c59 to 4fecd8c Compare February 2, 2023 15:12
@ianyong ianyong requested a review from RichDom2185 February 2, 2023 15:28
Copy link
Member

@RichDom2185 RichDom2185 left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@martin-henz martin-henz merged commit 403193f into master Feb 6, 2023
@ianyong ianyong deleted the fix-unnecessary-rerendering-of-mobile-side-content branch February 6, 2023 03:27
RichDom2185 added a commit to NUS-CS1101S/cadet-frontend that referenced this pull request Jul 15, 2023
…ce-academy#2338)

* Memoize SideContent & MobileSideContent only when exporting as default

* Update test snapshots

* Memoize onChange callback function

* Memoize session buttons in Playground

* Refactor session button to only access editor value when clicked

* Memoize callbacks passed into autorun button

* Specify autorun button props manually instead of using Lodash's pick

This is so that we can have more granular memoization to reduce
unnecessary re-rendering. Otherwise, the hidden '_owner' attribute
on the autorun React element object keeps changing, causing the
memoization of MobileSideContent to not work.

* Make use of 'workspaceLocation' in 'getEditorValue'

Currently, the 'Playground' component is also used by the SICP workspace.

Co-authored-by: Richard Dominick <[email protected]>

---------

Co-authored-by: Richard Dominick <[email protected]>
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.

Assessment Workspace: Module tab reloading on each keystroke in editor
4 participants