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

remove unnecessary re-renders to improve performance #160

Closed
wants to merge 20 commits into from

Conversation

pietrop
Copy link
Contributor

@pietrop pietrop commented May 15, 2019

Is your Pull Request request related to another issue in this repository ?

This issue #159

Describe what the PR does
Moved header into a component with shouldComponentUopdate false to test avoid unecessary re-renders - test

State whether the PR is ready for review or whether it needs extra work

work in progress

Additional context

with shouldComponentUopdate false to avoid unecessary re-renders - test
@pietrop pietrop mentioned this pull request May 15, 2019
@pietrop
Copy link
Contributor Author

pietrop commented May 17, 2019

@pietrop
Copy link
Contributor Author

pietrop commented May 17, 2019

@pietrop pietrop changed the title tests remove unnecessary re-renders remove unnecessary re-renders to improve performance May 20, 2019
@pietrop
Copy link
Contributor Author

pietrop commented May 20, 2019

To review this PR you need to run npm install as I’ve added react-visibility-sensor in package.json.

currentTime in TimedTextEditor


Updating on currentTime in TimedTextEditor might have a performance cost?

Or at the very lease it causing frequent re-renders

js
 if (nextProps.currentTime !== this.props.currentTime ) { return true; }




18ms + 17 to 24 re-renders calls

Vs
0.3ms + 17 to 24 re-renders calls if not updating TimedTextEditor on currentTime change (eg commenting out those 3 lines)

In current setup, draftJS Editor re-render should be separated from css injection in TimedTextEditor to use currentTime to show current word to at least avoid re-render DraftEditor on currentTime change.

react-visibility-sensor

Following up from this comment from @Laurian added VisibilitySensor in WrapperBlock, around the Speaker, Timecode, and draftJs Editor. This should avoid rendering any draftjs block unless it is visible

Downside of using VisibilitySensor is the text not in viewport is not rendered. Which means if you search with ctrl + f you it won’t show up in the results, so cannot search across the transcript.

However the performance boost should outweigh this, and a separate transcript wide search(and replace?) could be implemented at later stage if needed

Also not 100% sure how much of a performance boost react-visibility-sensor gives?

unnecessary re-renders

#159

Rough draft of React performances optimisation research notes from various docs and blogs can be found here

Used

  • why-did-you-update lib
  • React profiler tool
    
- [x] adding console.log in render method of components
  • refactored logic of some of the components communications to improve performance
  • use of shouldComponentUpdate
  • use of PureComponent

Performance for over 1 hour

Tested with
#150

Seems better but would need testing on lower performance windows PC with clip and transcript over 1 hour (eg 2hours min)

Also important to note (as pointed out by @Laurian) performance for longer content, is improved is paragraph blocks being edited are smaller (eg few lines) as opposed to half of the view height of more.

But not conclusive for now that this PR addresses the longer files performance issue. It does seem to reduce unnecessary re-renders tho.

immutable js warnings

why-did-you-update is commented out in /demo/app.js as it seems to slightly slows down performance when in development


if (process.env.NODE_ENV !== 'production') {
   const { whyDidYouUpdate } = require('why-did-you-update');
   whyDidYouUpdate(React, { exclude: [ /^HotKeysWrapper/ ] } );
}

However When using why-did-you-update to test unnecessary re-renders there’s a warning

immutable.js:4655 iterable.length has been deprecated, use iterable.size or iterable.count(). This warning will become a silent error in a future version. Error

As explained in this issue
facebookarchive/draft-js#950

DraftJS immutable JS dependency needs to be upgraded in DraftJs core library.


Still to do

  • Move CustomEditor into its own file form TimedTextEditor
  • Review CSS modules files are divided with concerns properly separated.
  • Capture some kind of ADR or doc note with main takeaway from these performance tweaks

Also addressed, small fix for
#147

@pietrop pietrop marked this pull request as ready for review May 20, 2019 09:34
@pietrop pietrop requested a review from jamesdools May 20, 2019 09:35
@pietrop
Copy link
Contributor Author

pietrop commented May 21, 2019

Something else to think about for a separate PR is the idea of pagination.

Context: DraftJS use case at FB is for small comments areas and Facebook notes. So not sure it has been tested agains large quantities of text or Many paragraphs (link to issue) or that they will ever have a use case to optimise for that (?).

Another option would be to reduce the amount of content in Draft at any given time, only to what is visible.

Eg at a high level it could use a pagination approach, similar to what is described in this blog post (without Redux!) so that every time scrolling up or down, it moves/changes the paragraphs that are visible in the editor.

Eg the wrapper component keeps an array of paragraphs, and a range of indexes to the once visible in draftJs, then some logic handles swapping the current paragraphs... etc..

Done in this way pagination would be hidden from the users UI/UX, eg it wouldn't look like paginated text, but it could provide a considerable performance boost.

@sshniro
Copy link
Contributor

sshniro commented Jul 25, 2019

Hi @pietrop is the paginating issue is still pending ? Shall I give it a try with React hooks and context ?

@pietrop
Copy link
Contributor Author

pietrop commented Jul 25, 2019

Hi @sshniro,
That would be awesome, PR welcome, in the last comment I started flashing out a direction for a possible solution. You are welcome to try that or some other approach.

I am not sure hooks and context would necessarily help with the specifics tho, as the solution might entail working around the draftJs component specific performance issues, what did you have in mind?

@sshniro
Copy link
Contributor

sshniro commented Jul 25, 2019

Aw sry my bad, I thought of handling the entire state out of draft , now only read the linked article. Ill play around with draft js and get back, thanks ! 👍

@pietrop
Copy link
Contributor Author

pietrop commented Jul 25, 2019

Awesome! Looking forward to it!
Any questions feel free to reach out, happy to help

@pietrop
Copy link
Contributor Author

pietrop commented Jul 31, 2019

Before

react-transcript-editor-unecessary re-renders

After

react-transcript-editor-unecessary re-renders - FIX

@pietrop pietrop mentioned this pull request Jul 31, 2019
package.json Show resolved Hide resolved
demo/app.js Show resolved Hide resolved
packages/components/media-player/index.js Show resolved Hide resolved
packages/components/media-player/index.js Show resolved Hide resolved
@@ -56,6 +46,64 @@ class TranscriptEditor extends React.Component {
return null;
}

// performance optimization
Copy link
Contributor

Choose a reason for hiding this comment

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

In this block, we have every single part of the state accounted for and checked, plus also one Prop (mediaUrl).

I checked there weren't any other special cases, but no it's looking at every single state property. So!

Instead of doing all that, we could write:

  shouldComponentUpdate = (nextProps, nextState) => {
     if (nextProps.mediaUrl !== this.props.mediaUrl) return true;

     return nextState !== this.state;
  }

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see any difference in performance or side-effects from that. If this is alright, I think we should do the same thing in the other places (as it's adding a lot of verbose and redundant code).

pietrop pushed a commit that referenced this pull request Aug 12, 2019
changes from James review #160
@pietrop
Copy link
Contributor Author

pietrop commented Aug 12, 2019

Thanks @jamesdools added most of the changes in #175.

3588b26 and #180

Going to do a separate PR for the should component update tweaks against the develop branch, to make those changes a little clearer and easier to review.

Closing this for now, as Develop is up to date with it.

@pietrop
Copy link
Contributor Author

pietrop commented Aug 12, 2019

addressed should component update in this standalone PR #182

pietrop pushed a commit that referenced this pull request Aug 13, 2019
* added support for docx - needs better integration altho it works

* adding timecodes and speakers to plain text export

* develop: Fix 159 performance problem (#171)

* moved header into a component

with shouldComponentUopdate false to avoid unecessary re-renders - test

* moved Header component into separate file

+removed unused styling, commented out for now in case it's needed, eg in mobile view?

* moved playback_rates const into separate file

* optimised re-render of playback rate

* optimise re-render for VideoPlayer

* added some notes - draft

on how to prevent uncessary re-renders in React

* Added some comments

* small note in docs

about using console.log in render to measure performance

* ammend to notes

* Update 2019-05-16-prevent-unnecessary-re-renders-in-react.md

* notes update

* notes fix

* trying out why-did-you-update

* updated MediaPlayer and subcomponents

* made ToolTip 'how does this work' into it's own component

* updated Demo app to reduce unecessary re-renders

* added react-visibility-sensor

* refactor settings

* removed unecessary attributes from state of components + WrapperBlock performance tweak using react-visibility-sensor

* develop: Update timestamps diff (#172)

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added documentation

* Merged timer for updating the timestamps and local save.

* Selection state is now kept across updates to timestamps

* Fixed bug where words with punctuation always are considered as new words. Timestamp update function now also uses the alignWords function directly instead of alignJSONText, removing some overhead.

* Fixed small bug which raised an error if an empty block was present during timestamp update

* Changed time of timestamp-update. Now re-calculates the timestamps after 5 seconds if the transcript has been edited or if the user saves the transcript manually with the save button

* Code cleanup

* develop: Murezzda update timestamps diff (#173)

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added documentation

* Merged timer for updating the timestamps and local save.

* Selection state is now kept across updates to timestamps

* Fixed bug where words with punctuation always are considered as new words. Timestamp update function now also uses the alignWords function directly instead of alignJSONText, removing some overhead.

* Fixed small bug which raised an error if an empty block was present during timestamp update

* Changed time of timestamp-update. Now re-calculates the timestamps after 5 seconds if the transcript has been edited or if the user saves the transcript manually with the save button

* Code cleanup

* some changes to show sudgestions for PR

* added some of changes sudgested in PR

* Update package.json

* develop: Murezzda update timestamps diff dpe groups words by speaker (#174)

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added documentation

* Merged timer for updating the timestamps and local save.

* Selection state is now kept across updates to timestamps

* Fixed bug where words with punctuation always are considered as new words. Timestamp update function now also uses the alignWords function directly instead of alignJSONText, removing some overhead.

* Fixed small bug which raised an error if an empty block was present during timestamp update

* Changed time of timestamp-update. Now re-calculates the timestamps after 5 seconds if the transcript has been edited or if the user saves the transcript manually with the save button

* Code cleanup

* some changes to show sudgestions for PR

* added some of changes sudgested in PR

* adjusted DPE adapter

so that it preserves paragraphs break within contiguos speakers

* fixed one test

* commented out auto align

left aligning as a step before save btn and before export function, rather then as a step that happens everytime autosave is triggered, as that might be unecessary, and add performance overhead, I also noticed the cursor position jumped after realignement, thought something was been put in place to preserve/avoid that?

* updated package-lock

* fixed vulneranilities

* Getting ready to publish alpha

* 1.0.4-alpha.0

* 1.0.4@alpha

* fixed notes

* changing speaker and timecodes to be unselectable

* 1.0.4-alpha.1

* 1.0.4-alpha.1

unselectabel speakers and timecodes

* fix speaker and timecodes at paragraph level after realignement

* 1.0.4-alpha.2

* fixed docx integration

* Subtitles export (#168)

* added option to export srt files

and layout to export other type of captions with auto segmentation of lines

* added support for other subtitles formats

* fixed npm audit

* implemented export in UI

* fixed test

added sample files for adding tests for subtitle composer module at later stage

* added optional analytics

for export download options

* updated CSS

* 1.0.4-alpha.3

* fixed subtiles segmentation

algo was picking the wrong words from the list

* moved PR template in github folder

* cleaned up code for subtitles parsing

* 1.0.4-alpha.4

* fixed alignement algo

after interpolation words time boundares  where overlapping

* fixed interpolation

* fixed filename of word doc export

* fixed TimeBox

and playback rate not working

* 1.0.4-alpha.5

* removed scroll sync (#181)

fix #180

* refactor

changes from James review #160

* Develop branch -  should component update refactor (#182)

* Refactor should component updatre for transcript editor

* Refactor should component updatre for PlayerControls

* Refactor should component updatre for TimeBox

* Refactor should component update for ProgressBar

* Refactor should component update for TimedTextEditor

* Refactor should component update for Header

* fix from PR review

Fixed from James comments from #144 (review)

* Update package.json

* Update package.json
emettely pushed a commit that referenced this pull request Sep 17, 2019
@jamesdools jamesdools deleted the fix-159-performance-problem branch September 18, 2019 10:22
@jamesdools jamesdools restored the fix-159-performance-problem branch September 18, 2019 10:22
@jamesdools jamesdools deleted the fix-159-performance-problem branch December 4, 2019 12:55
codegod2222 added a commit to codegod2222/transcript-editor that referenced this pull request Jan 12, 2023
* added support for docx - needs better integration altho it works

* adding timecodes and speakers to plain text export

* develop: Fix 159 performance problem (#171)

* moved header into a component

with shouldComponentUopdate false to avoid unecessary re-renders - test

* moved Header component into separate file

+removed unused styling, commented out for now in case it's needed, eg in mobile view?

* moved playback_rates const into separate file

* optimised re-render of playback rate

* optimise re-render for VideoPlayer

* added some notes - draft

on how to prevent uncessary re-renders in React

* Added some comments

* small note in docs

about using console.log in render to measure performance

* ammend to notes

* Update 2019-05-16-prevent-unnecessary-re-renders-in-react.md

* notes update

* notes fix

* trying out why-did-you-update

* updated MediaPlayer and subcomponents

* made ToolTip 'how does this work' into it's own component

* updated Demo app to reduce unecessary re-renders

* added react-visibility-sensor

* refactor settings

* removed unecessary attributes from state of components + WrapperBlock performance tweak using react-visibility-sensor

* develop: Update timestamps diff (#172)

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added documentation

* Merged timer for updating the timestamps and local save.

* Selection state is now kept across updates to timestamps

* Fixed bug where words with punctuation always are considered as new words. Timestamp update function now also uses the alignWords function directly instead of alignJSONText, removing some overhead.

* Fixed small bug which raised an error if an empty block was present during timestamp update

* Changed time of timestamp-update. Now re-calculates the timestamps after 5 seconds if the transcript has been edited or if the user saves the transcript manually with the save button

* Code cleanup

* develop: Murezzda update timestamps diff (#173)

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added documentation

* Merged timer for updating the timestamps and local save.

* Selection state is now kept across updates to timestamps

* Fixed bug where words with punctuation always are considered as new words. Timestamp update function now also uses the alignWords function directly instead of alignJSONText, removing some overhead.

* Fixed small bug which raised an error if an empty block was present during timestamp update

* Changed time of timestamp-update. Now re-calculates the timestamps after 5 seconds if the transcript has been edited or if the user saves the transcript manually with the save button

* Code cleanup

* some changes to show sudgestions for PR

* added some of changes sudgested in PR

* Update package.json

* develop: Murezzda update timestamps diff dpe groups words by speaker (#174)

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added timestamp update via diff tool

* Added missing function

* Commited intermediate state

* Rewrote timestamp alignment and differ to be integrated in each other instead of doing a 2-step process.

* Update Timestamps now works correctly.

* Fixed errors from rebase, removed debug code

* Moved UpdateTimestamp into its own folder.

* added updateTimestampsSSTAlign which updates the timestamps with the sst-align code

* Added documentation

* Merged timer for updating the timestamps and local save.

* Selection state is now kept across updates to timestamps

* Fixed bug where words with punctuation always are considered as new words. Timestamp update function now also uses the alignWords function directly instead of alignJSONText, removing some overhead.

* Fixed small bug which raised an error if an empty block was present during timestamp update

* Changed time of timestamp-update. Now re-calculates the timestamps after 5 seconds if the transcript has been edited or if the user saves the transcript manually with the save button

* Code cleanup

* some changes to show sudgestions for PR

* added some of changes sudgested in PR

* adjusted DPE adapter

so that it preserves paragraphs break within contiguos speakers

* fixed one test

* commented out auto align

left aligning as a step before save btn and before export function, rather then as a step that happens everytime autosave is triggered, as that might be unecessary, and add performance overhead, I also noticed the cursor position jumped after realignement, thought something was been put in place to preserve/avoid that?

* updated package-lock

* fixed vulneranilities

* Getting ready to publish alpha

* 1.0.4-alpha.0

* 1.0.4@alpha

* fixed notes

* changing speaker and timecodes to be unselectable

* 1.0.4-alpha.1

* 1.0.4-alpha.1

unselectabel speakers and timecodes

* fix speaker and timecodes at paragraph level after realignement

* 1.0.4-alpha.2

* fixed docx integration

* Subtitles export (#168)

* added option to export srt files

and layout to export other type of captions with auto segmentation of lines

* added support for other subtitles formats

* fixed npm audit

* implemented export in UI

* fixed test

added sample files for adding tests for subtitle composer module at later stage

* added optional analytics

for export download options

* updated CSS

* 1.0.4-alpha.3

* fixed subtiles segmentation

algo was picking the wrong words from the list

* moved PR template in github folder

* cleaned up code for subtitles parsing

* 1.0.4-alpha.4

* fixed alignement algo

after interpolation words time boundares  where overlapping

* fixed interpolation

* fixed filename of word doc export

* fixed TimeBox

and playback rate not working

* 1.0.4-alpha.5

* removed scroll sync (#181)

fix bbc/react-transcript-editor#180

* refactor

changes from James review bbc/react-transcript-editor#160

* Develop branch -  should component update refactor (#182)

* Refactor should component updatre for transcript editor

* Refactor should component updatre for PlayerControls

* Refactor should component updatre for TimeBox

* Refactor should component update for ProgressBar

* Refactor should component update for TimedTextEditor

* Refactor should component update for Header

* fix from PR review

Fixed from James comments from bbc/react-transcript-editor#144 (review)

* Update package.json

* Update package.json
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.

None yet

3 participants