On devices without a top-notch CPU, typing in the rich text editor is laggy even in the very basic community test suite's "Post" collection. Lags can be up to multiple seconds. This lag can be reproduced by e.g. throttling the CPU by 6x on a MacBook Pro with M1 Pro chip and 32GB of RAM. Typing at regular speed already stutters, and the Chromium performance monitor shows 100% peak CPU utilization. Under the same circumstances, the Lexical rich text editor on https://playground.lexical.dev/ does not exhibit the same laggy UI reactions. The issue was narrowed down to the editor state serialization that was so far executed on every change in `Field.tsx` and utilizing more than 1 frame's worth of CPU time. This PR attempts to address the issue by asking the browser to queue the work in moments where it doesn't interfere with UI responsiveness, via `requestIdleCallback`. To verify this change, simulate a slow CPU by setting `CPU: 6x slowdown` in the Chromium `Performance` Dev Tool panel, and then type into the community test suite's example post's rich text field. I did not collect exhaustive benchmarks, since numbers are system specific and the impact of the code change is simple to verify. Demos: Before, whole words are not appearing while typing, but then appear all at once, INP is 6s, and CPU at 100% basically the whole interaction time: https://github.com/user-attachments/assets/535653d5-c9e6-4189-a0e0-f71d39c43c31 After: Most letters appear without delay, individual letters can be slightly delayed, but INP is much more reasonable 350ms, and CPU has enough bandwidth to drop below 100% utilization: https://github.com/user-attachments/assets/e627bf50-b441-41de-b3a3-7ba5443ff049 ⬆️ This recording is from an earlier solution attempt with 500ms debouncing. The current approach with `requestIdleCallback` increases CPU usage back to a close 100%, but the INP is further reduced to 2xxms on my machine, and the perceived UI laggyness is comparable to this recording. --- This PR only addresses the rich text editor, because that's where the performance was a severe usability deal-breaker for real world usage. Presumably other input fields where users trigger a lot of change events in succession such as text, textarea, number, and JSON fields might also benefit from similar debouncing.
Payload Lexical Rich Text Editor
Lexical Rich Text Editor for Payload.
Installation
npm install @payloadcms/richtext-lexical
Usage
import { buildConfig } from 'payload'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
export default buildConfig({
editor: lexicalEditor({}),
// ...rest of config
})
More detailed usage can be found in the Payload Docs.