Skip to content

Comments

refactor(texteditor): lazy load heavy extensions and general optimization#5304

Merged
nucleogenesis merged 11 commits intolearningequality:unstablefrom
habibayman:refactor/RTE-performance
Aug 28, 2025
Merged

refactor(texteditor): lazy load heavy extensions and general optimization#5304
nucleogenesis merged 11 commits intolearningequality:unstablefrom
habibayman:refactor/RTE-performance

Conversation

@habibayman
Copy link
Member

@habibayman habibayman commented Aug 16, 2025

Summary

Utilized webpack's code splitting to lazy load mathlive extension as its size is significantly large. We knew this before choosing the library but decided on it despite that for other perks, mainly its a11y features. more on that can be found in this Notion page: notion.so/Replacing-Formula-Editor

I used a straight forward dynamic import approach, that didn't directly work with the Math extension configuration, as it must expect a component (not a promise) for a NodeView component.
So I created the <LazyMathNodeView /> component to delegate the dynamic importing to.

for the few milliseconds while the library is loading, existing math elements are shown as latex, I thought that would be better than just a loading spinner.

I also added general optimizations around files for a better DOM handling (more refs, more caching, throttling,etc)

References


Reviewer guidance

  • formulas menu opens and works as expected
  • formulas that were already in the editor's content appear on page reload fine
  • styles are applied correctly and no errors appear in the console

@habibayman habibayman marked this pull request as ready for review August 17, 2025 19:33
@habibayman
Copy link
Member Author

Hello @MisRob :)
I think you may be interested in seeing these commits, I added them based on your guidance.
No pressure though if you're busy! I know Marcella & Jacob will be doing a thorough review anyways!

Copy link
Member

@nucleogenesis nucleogenesis left a comment

Choose a reason for hiding this comment

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

I spun it up and it worked well! I've added some comments, questions and a couple of change requests.

One thing I noticed (which may not be related to the changes in this PR) - but when I click the editor somewhere, it doesn't focus the actual input. So - an empty editor requires that I put my mouse directly on the invisible input line in order to get my focus there to type.

If the user clicks anywhere on the editor that isn't itself interactive, then the input of the editor should be focused. Hopefully this image helps explain what I mean

image

**This might be just my own opinion - ** so let's chat w/ @marcellamaki & @radinamatic about the expected behavior here before making changes on this front specifically.

Comment on lines 28 to 35
const throttledUpdatePosition = () => {
if (scrollRaf) {
cancelAnimationFrame(scrollRaf);
}
scrollRaf = requestAnimationFrame(updatePosition);
};

const throttledHandleResize = () => {
Copy link
Member

Choose a reason for hiding this comment

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

Did you plan to use something like lodash/throttle here? The use case here is a bit of an edge case which makes me think it'll be relatively rare for someone to be scrolling the page and/or resizing the screen while looking for math equations or uploading an image.

However, it's good practice to throttle functions like this that will be called repeatedly during resize & scrolling events. I suggest looking at lodash/throttle.

Copy link
Member Author

@habibayman habibayman Aug 19, 2025

Choose a reason for hiding this comment

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

If I didn't understand what you're saying or I'm talking about another point please correct me :)

I actually think scrolling the page while the modals are open is very common, the formula menu for example is relatively large and I think the scenario I am capturing in the demo will happen very often.
I think the general usage of the composable is inevitable but you're right it may happen a lot but it doesn't happen for that long for us to be looking into serious ways for optimization. but if the optimization is simple, why not!

and thank you for the function suggestion, I used it for its simpleness but added a wait time equivalent to what requestAnimationFrame used to give us for a smooth behavior.

scroll+formulaMenu.webm

@habibayman
Copy link
Member Author

habibayman commented Aug 19, 2025

@nucleogenesis

when I click the editor somewhere, it doesn't focus the actual input

This is the default behavior yes. I tried it out in the editor example of tiptap docs.
steps to try:

  1. go to https://tiptap.dev/docs/examples/basics/default-text-editor
  2. empty the content of the editor
  3. try to replicate the same behavior

If that's something that you would consider blocking, I will try to change that. 👍🏻

@habibayman habibayman force-pushed the refactor/RTE-performance branch from 3ecdb69 to 2b03d91 Compare August 28, 2025 17:11
@habibayman habibayman force-pushed the refactor/RTE-performance branch from 092c148 to d0c08f2 Compare August 28, 2025 17:19
Copy link
Member

@nucleogenesis nucleogenesis left a comment

Choose a reason for hiding this comment

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

Smoke tested it again after the substantial rebase. I tested all of the formatting & insertion actions on a couple different screen sizes without issue.

@nucleogenesis nucleogenesis merged commit 2778563 into learningequality:unstable Aug 28, 2025
13 checks passed
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.

[New Rich Text Editor]: improve performance by lazy loading heavy extensions

2 participants