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

The editor slows down with lots of content, and only with ckeditor5-vue #153

Closed
marcellofuschi opened this issue Sep 6, 2020 · 9 comments · Fixed by #156
Closed

The editor slows down with lots of content, and only with ckeditor5-vue #153

marcellofuschi opened this issue Sep 6, 2020 · 9 comments · Fixed by #156
Assignees
Milestone

Comments

@marcellofuschi
Copy link

I've been testing my CKEditor 5 (version 22) implementation with ckeditor5-vue.

I tried both with and w/o ckeditor5-vue and I noticed a drastic difference in the time it takes the editor to change the content when there's already lots of it. E.g., when you try to write some letters in the editor it takes several seconds for them to actually appear. That doesn't happen when you're instantiating the editor without using ckeditor5-vue.

To reproduce the problem, you may just paste into the editor the content of this file:
test_long_content.txt

@FilipTokarski
Copy link
Member

Hi, thanks for the report, I can reproduce this issue. It seems that if the content is quite big and contains special characters, it causes Vue integration to lag. I couldn't reproduce it on CKEditor 5 demo.

Here's my test content: https://gist.github.com/FilipTokarski/ce03de49fb6b2fa05ddea402fa516286

cc @oleq Can you take a look at this?

@oleq
Copy link
Member

oleq commented Sep 11, 2020

I agree there is a problem but I don't see any sensible solution.

The thing is each time we debounce() the Vue input event we call Editor.getData(). When there's a lot of content this task is time-consuming and blocks the main thread. There's little we can do because the data must be emitted and there's no other way to obtain it.

On top of it, a couple of weeks ago we changed the debounce() to fire on the leading edge (to prevent some race conditions), which means the lag associated with Editor.getData() happens immediately as you start typing (previously on the trailing edge (when you stopped) provided you type faster than 300ms-per-character because this is the debounce() timeout in the integration).

@oleq
Copy link
Member

oleq commented Sep 11, 2020

@FilipTokarski Can you take a look at React and Angular integrations and stress them out with the same data? I'm curious about the results.

@marcellofuschi
Copy link
Author

marcellofuschi commented Sep 11, 2020

I am also wondering whether the official CKEditor's Autosave plugin (which supposedly should behave in a similar way) has the same performance problem.

@oleq
Copy link
Member

oleq commented Sep 11, 2020

I am also wondering whether the official CKEditor's Autosave plugin (which supposedly should behave in a similar way) has the same performance problem.

You're probably right (but only to some extent). Autosave works on the trailing edge debounce with 1000ms timeout. So only when you stop typing and wait one second the Editor.getData() will occur.


Anyway, what if we increase the timeout in the Vue integration to 1000ms as well? The whole point of this.$emit('input') is making sure the v-model integration is possible. Maybe we could make this UX a little less annoying simply by that. 

What use-cases related to v-model come into play when it comes to a WYSIWYG editor? Validation? Something else? Could increasing 300ms to 1000ms be too extreme (like you have to wait for a second for the two-way-data binding to kick in ) @marcellofuschi?

@marcellofuschi
Copy link
Author

marcellofuschi commented Sep 11, 2020

I tried changing the debounce() wait time from 300ms to 1000ms as you suggested but unfortunately it doesn't seem to help. I'm not sure why, but there's still a delay that makes writing impractical. Any other clue?

@marcellofuschi
Copy link
Author

I tried removing parts of the Vue component and testing to see if the editor slows down without them. Turns out that completely removing the methods and watchers doesn't improve the performance. The only thing that seemed to fix the problem was removing the line this.instance = editor in the editor setup callback. Maybe Vue's reactivity mechanism is inefficient when used on the editor instance?
I'll try to dig a bit deeper...

@FilipTokarski
Copy link
Member

@FilipTokarski Can you take a look at React and Angular integrations and stress them out with the same data? I'm curious about the results.

I checked it once again with the content provided in the first comment ☝️ . Only Vue has a noticeable lag, React and Angular seem to work fine.

@oleq
Copy link
Member

oleq commented Sep 17, 2020

I tried removing parts of the Vue component and testing to see if the editor slows down without them. Turns out that completely removing the methods and watchers doesn't improve the performance. The only thing that seemed to fix the problem was removing the line this.instance = editor in the editor setup callback. Maybe Vue's reactivity mechanism is inefficient when used on the editor instance?
I'll try to dig a bit deeper...

You were right, I confirm this 🎉 

Getting rid of data() entirely in the component solves the issue. I think the reactive system of Vue takes over and watches everything in editor instance internals (there are a toooooons of them) and this caused the problem.

The difference is colossal (typing a single character takes ~150ms with the reproducible bug and ~35ms when it's gone).


Update: I just realized it's enough to prefix the instance prop with $_ to exclude it from Vue internal shenanigans. Here's the PR #156. Can you confirm @marcellofuschi that it works for you?

@oleq oleq self-assigned this Sep 17, 2020
@oleq oleq added this to the iteration 36 milestone Sep 17, 2020
pomek added a commit that referenced this issue Sep 18, 2020
Fix: The editor should now slow down with lots of content when using the integration. Closes #153.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment