-
-
Notifications
You must be signed in to change notification settings - Fork 415
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
fix: paste large content with operational ui #7796
fix: paste large content with operational ui #7796
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Skipped Deployment
|
Your org has enabled the Graphite merge queue for merging into masterAdd the label “merge” to the PR and Graphite will automatically add it to the merge queue when it’s ready to merge. You must have a Graphite account and log in to Graphite in order to use the merge queue. Sign up using this link. |
This stack of pull requests is managed by Graphite. Learn more about stacking. Join @Saul-Mirone and the rest of your teammates on Graphite |
271983c
to
2063e22
Compare
2063e22
to
14046cf
Compare
## Features - toeverything/blocksuite#7807 @zzj3720 - toeverything/blocksuite#7786 @zzj3720 - toeverything/blocksuite#7797 @donteatfriedrice ## Bugfix - toeverything/blocksuite#7814 @fundon - toeverything/blocksuite#7812 @L-Sun - toeverything/blocksuite#7792 @fundon - toeverything/blocksuite#7788 @fundon - toeverything/blocksuite#7805 @doouding - toeverything/blocksuite#7810 @zzj3720 - toeverything/blocksuite#7802 @L-Sun - toeverything/blocksuite#7804 @L-Sun - toeverything/blocksuite#7799 @Saul-Mirone - toeverything/blocksuite#7753 @CatsJuice - toeverything/blocksuite#7798 @zzj3720 - toeverything/blocksuite#7796 @Saul-Mirone - toeverything/blocksuite#7793 @doouding - toeverything/blocksuite#7795 @Saul-Mirone - toeverything/blocksuite#7791 @fundon - toeverything/blocksuite#7747 @doouding - toeverything/blocksuite#7785 @fundon - toeverything/blocksuite#7784 @akumatus ## Misc - toeverything/blocksuite#7800 @Saul-Mirone - toeverything/blocksuite#7790 @fourdim
- toeverything/blocksuite#7807 @zzj3720 - toeverything/blocksuite#7786 @zzj3720 - toeverything/blocksuite#7797 @donteatfriedrice - toeverything/blocksuite#7814 @fundon - toeverything/blocksuite#7812 @L-Sun - toeverything/blocksuite#7792 @fundon - toeverything/blocksuite#7788 @fundon - toeverything/blocksuite#7805 @doouding - toeverything/blocksuite#7810 @zzj3720 - toeverything/blocksuite#7802 @L-Sun - toeverything/blocksuite#7804 @L-Sun - toeverything/blocksuite#7799 @Saul-Mirone - toeverything/blocksuite#7753 @CatsJuice - toeverything/blocksuite#7798 @zzj3720 - toeverything/blocksuite#7796 @Saul-Mirone - toeverything/blocksuite#7793 @doouding - toeverything/blocksuite#7795 @Saul-Mirone - toeverything/blocksuite#7791 @fundon - toeverything/blocksuite#7747 @doouding - toeverything/blocksuite#7785 @fundon - toeverything/blocksuite#7784 @akumatus - toeverything/blocksuite#7800 @Saul-Mirone - toeverything/blocksuite#7790 @fourdim
- toeverything/blocksuite#7807 @zzj3720 - toeverything/blocksuite#7786 @zzj3720 - toeverything/blocksuite#7797 @donteatfriedrice - toeverything/blocksuite#7814 @fundon - toeverything/blocksuite#7812 @L-Sun - toeverything/blocksuite#7792 @fundon - toeverything/blocksuite#7788 @fundon - toeverything/blocksuite#7805 @doouding - toeverything/blocksuite#7810 @zzj3720 - toeverything/blocksuite#7802 @L-Sun - toeverything/blocksuite#7804 @L-Sun - toeverything/blocksuite#7799 @Saul-Mirone - toeverything/blocksuite#7753 @CatsJuice - toeverything/blocksuite#7798 @zzj3720 - toeverything/blocksuite#7796 @Saul-Mirone - toeverything/blocksuite#7793 @doouding - toeverything/blocksuite#7795 @Saul-Mirone - toeverything/blocksuite#7791 @fundon - toeverything/blocksuite#7747 @doouding - toeverything/blocksuite#7785 @fundon - toeverything/blocksuite#7784 @akumatus - toeverything/blocksuite#7800 @Saul-Mirone - toeverything/blocksuite#7790 @fourdim
@@ -470,6 +470,11 @@ export class Job { | |||
children, | |||
}); | |||
|
|||
const nextTick = | |||
typeof window !== 'undefined' | |||
? window.requestAnimationFrame |
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.
This is considered too slow in #8380. A brief perf test could be found in
The non-blocking pasting could be MUCH slower.
Try this test file with ~1000 lines, the sync pasting completes immediately but async pasting takes ~10s.
I think the downside switching to sync pasting may be about image importing. Not sure if we can make some improvement on the strategy.
Close #8380 ## Problem The original process of converting snapshot JSON to blocks was significantly slowed to ensure UI responsiveness. It involved two types of async computations: * Asynchronously converting snapshots to draft models. * Asynchronously inserting draft models into the block tree using `doc.addBlock`. Original import sequence: ``` Convert snapshot node A Insert block A Wait for tick Convert snapshot node B Insert block B Wait for tick Convert snapshot node C Insert block C Wait for tick ... ``` Despite `doc.addBlock` being synchronous, a `requestAnimationFrame` interval was added after each block insertion to prevent UI blocking. This resulted in long processing times when pasting thousands of blocks: https://github.com/user-attachments/assets/3a6379c9-621e-490e-a79f-4377494d5915 ## New Design This PR reimplements the process: 1. Convert all snapshot nodes first, either using `Promise.all` or sequential awaits: Firstly we flatten the block tree, asynchronously convert all nodes, then rebuild the tree. 2. Insert the converted draft block tree in batches, **waiting for a tick after each _batch_ instead of after each _block_**. This optimizes both block tree conversion and insertion while maintaining UI responsiveness. ## Performance Tests ### Comparing serial vs parallel (`Promise.all`) snapshot tree conversion: - 1000 blocks: `Promise.all` 4.8ms, series 2.8ms - 60 images: `Promise.all` 2.8ms, series 2.2ms Serial conversion proved faster and was implemented in b90d736. The flatten-rebuild logic was retained for scalability. ### Pasting 1000 blocks performance: Original: ~10s (see screen recording above) New: ~1s with maintained UI responsiveness https://github.com/user-attachments/assets/0202330a-66ce-47f3-b220-44a4e9c7c37d ### Switching to imported documents: Loading the block tree into DOM (by switching to an imported document) causes similar delays in both implementations. --- Legacy first take: <details> This PR significantly improves the performance of block import operations by addressing several inefficiencies in the current implementation: - Removed the need to wait for `requestAnimationFrame` after each block insertion (see #7796), which was causing significant slowdowns. - <del>Fixed the batch mechanism (see #7790) that wasn't properly enabled, replacing serial execution with true parallel processing.</del> - Instead of executing all remaining tasks at once after 100 items (still causing UI freezes), we now process tasks in consistent batches of 100 per tick. - Replaced `setTimeout` with `requestIdleCallback` for batch ticks, better utilizing idle browser time. These optimizations result in much faster block imports while maintaining UI responsiveness. The new implementation processes 100 tasks per tick, striking a balance between speed and smooth user experience. Tested using [clipboard-test.md](https://github.com/user-attachments/files/17088183/clipboard-test.md) with 1000 line and 600 blocks: ## Before (took ~10s to paste) https://github.com/user-attachments/assets/3a6379c9-621e-490e-a79f-4377494d5915 ## After (instant response without blocking UI) https://github.com/user-attachments/assets/dea7c1f9-a8c1-4926-92b7-f5cb40957fad </details>
Screen.Recording.2024-08-01.at.10.55.25.mov