-
Notifications
You must be signed in to change notification settings - Fork 2.7k
perf: actually debounce rich text editor field value updates to only process latest state #12086
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
perf: actually debounce rich text editor field value updates to only process latest state #12086
Conversation
Follow-up work to payloadcms#12046: Debounces rich text editor `setState()` calls. Using `requestIdleCallback` leads to better scheduling of change event handling in the rich text editor, but on CPU-starved clients, this leads to a large backlog of unprocessed idle callbacks. Since idle callbacks are called by the browser in submission order, the latest callback will be processed last, potentially leading to large time delays between a user typing, and the form state having been updated. An example: When a user types "I", and the change events for the character "I" is scheduled to happen in the next browser idle time, but then the user goes on to type "love Payload", there will be 12 more callbacks scheduled. On a slow system it's preferable if the browser right away only processes the event that has the full editor state "I love Payload", instead of only processing that after 11 other idle callbacks. So this code change keeps track when requesting an idle callback and cancels the previous one when a new change event with an updated editor state occurrs.
7f86b5b
to
c2472ac
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The linter indicates that the "React Hook useCallback has a missing dependency: 'updateFieldValue'."
Previously, the eslint rule could be disabled on this line, since the only external dependency on updateFiledValue
is setValue
, which is already in the dependency array.
However, with the introduction of the React compiler, even if we know what we're doing, it's necessary not to violate the linter rules, since they are the same ones used by the React compiler, and a violation would mean the file would be skipped.
The solution here is either to add updateFieldValue
to the dependency array or use our useEffectEvent hook, which mimics the experimental React hook with the same name.
You didn't need to know this, of course. Our codebase doesn't yet have 100% coverage of the React compiler, but that's the goal we're aiming for.
Inlines function into `useCallback`, which solves the linting issue that the `useCallback` had a missing dependency `updateFieldValue`. Addresses payloadcms#12086 (review).
@GermanJablo Thank you for the pointer, addressed the dependencies of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
…process latest state (#12086) Follow-up work to #12046, which was misnamed. It improved UI responsiveness of the rich text field on CPU-limited clients, but didn't actually reduce work by debouncing. It only improved scheduling. Using `requestIdleCallback` lead to better scheduling of change event handling in the rich text editor, but on CPU-starved clients, this leads to a large backlog of unprocessed idle callbacks. Since idle callbacks are called by the browser in submission order, the latest callback will be processed last, potentially leading to large time delays between a user typing, and the form state having been updated. An example: When a user types "I", and the change events for the character "I" is scheduled to happen in the next browser idle time, but then the user goes on to type "love Payload", there will be 12 more callbacks scheduled. On a slow system it's preferable if the browser right away only processes the event that has the full editor state "I love Payload", instead of only processing that after 11 other idle callbacks. So this code change keeps track when requesting an idle callback and cancels the previous one when a new change event with an updated editor state occurs.
🚀 This is included in version v3.38.0 |
…process latest state (#12086) Follow-up work to #12046, which was misnamed. It improved UI responsiveness of the rich text field on CPU-limited clients, but didn't actually reduce work by debouncing. It only improved scheduling. Using `requestIdleCallback` lead to better scheduling of change event handling in the rich text editor, but on CPU-starved clients, this leads to a large backlog of unprocessed idle callbacks. Since idle callbacks are called by the browser in submission order, the latest callback will be processed last, potentially leading to large time delays between a user typing, and the form state having been updated. An example: When a user types "I", and the change events for the character "I" is scheduled to happen in the next browser idle time, but then the user goes on to type "love Payload", there will be 12 more callbacks scheduled. On a slow system it's preferable if the browser right away only processes the event that has the full editor state "I love Payload", instead of only processing that after 11 other idle callbacks. So this code change keeps track when requesting an idle callback and cancels the previous one when a new change event with an updated editor state occurs.
Follow-up work to #12046, which was misnamed. It improved UI responsiveness of the rich text field on CPU-limited clients, but didn't actually reduce work by debouncing. It only improved scheduling.
Using
requestIdleCallback
lead to better scheduling of change event handling in the rich text editor, but on CPU-starved clients, this leads to a large backlog of unprocessed idle callbacks. Since idle callbacks are called by the browser in submission order, the latest callback will be processed last, potentially leading to large time delays between a user typing, and the form state having been updated. An example: When a user types "I", and the change events for the character "I" is scheduled to happen in the next browser idle time, but then the user goes on to type "love Payload", there will be 12 more callbacks scheduled. On a slow system it's preferable if the browser right away only processes the event that has the full editor state "I love Payload", instead of only processing that after 11 other idle callbacks.So this code change keeps track when requesting an idle callback and cancels the previous one when a new change event with an updated editor state occurs.