Philipp Schneider 101f7658f7 perf(richtext-lexical): debounce field onChange handler (#12046)
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.
2025-04-10 08:41:37 -03:00
2024-08-16 15:22:56 -04:00
2024-08-13 12:54:33 -04:00
2024-08-29 23:29:40 -04:00
2025-03-05 19:14:35 +00:00

Payload headless CMS Admin panel built with React

GitHub Workflow Status   Discord   npm   npm   npm   Payload Twitter


Explore the Docs · Community Help · Roadmap · View G2 Reviews


Important

🎉 We've released 3.0! Star this repo or keep an eye on it to follow along.

Payload is the first-ever Next.js native CMS that can install directly in your existing /app folder. It's the start of a new era for headless CMS.

Benefits over a regular CMS

  • Deploy anywhere, including serverless on Vercel for free
  • Combine your front+backend in the same /app folder if you want
  • Don't sign up for yet another SaaS - Payload is open source
  • Query your database in React Server Components
  • Both admin and backend are 100% extensible
  • No vendor lock-in
  • Never touch ancient WP code again
  • Build faster, never hit a roadblock

Quickstart

Before beginning to work with Payload, make sure you have all of the required software.

pnpx create-payload-app@latest

If you're new to Payload, you should start with the website template (pnpx create-payload-app@latest -t website). It shows how to do everything - including custom Rich Text blocks, on-demand revalidation, live preview, and more. It comes with a frontend built with Tailwind all in one /app folder.

One-click templates

Jumpstart your next project by starting with a pre-made template. These are production-ready, end-to-end solutions designed to get you to market as fast as possible.

🌐 Website

Build any kind of website, blog, or portfolio from small to enterprise. Comes with a fully functional front-end built with RSCs and Tailwind.

We're constantly adding more templates to our Templates Directory. If you maintain your own template, consider adding the payload-template topic to your GitHub repository for others to find.

Features

Request Feature

🗒️ Documentation

Check out the Payload website to find in-depth documentation for everything that Payload offers.

Migrating from v2 to v3? Check out the 3.0 Migration Guide on how to do it.

🙋 Contributing

If you want to add contributions to this repository, please follow the instructions in contributing.md.

📚 Examples

The Examples Directory is a great resource for learning how to setup Payload in a variety of different ways, but you can also find great examples in our blog and throughout our social media.

If you'd like to run the examples, you can use create-payload-app to create a project from one:

npx create-payload-app --example example_name

You can see more examples at:

🔌 Plugins

Payload is highly extensible and allows you to install or distribute plugins that add or remove functionality. There are both officially-supported and community-supported plugins available. If you maintain your own plugin, consider adding the payload-plugin topic to your GitHub repository for others to find.

🚨 Need help?

There are lots of good conversations and resources in our Github Discussions board and our Discord Server. If you're struggling with something, chances are, someone's already solved what you're up against. 👇

Like what we're doing? Give us a star

payload-github-star

👏 Thanks to all our contributors

Description
No description provided
Readme 110 MiB
Languages
TypeScript 95.9%
SCSS 2.7%
JavaScript 1.1%
CSS 0.2%
Dockerfile 0.1%