From bc2769f3d36227e1ecc2769737e9e8404fe0602e Mon Sep 17 00:00:00 2001 From: Flrande <50035259+Flrande@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:31:54 +0800 Subject: [PATCH] fix: improve code block performance (#6236) --- .../_common/components/rich-text/rich-text.ts | 4 +- packages/blocks/src/note-block/note-block.ts | 4 +- .../framework/inline/src/services/range.ts | 5 ++- .../framework/lit/src/utils/range-binding.ts | 38 ++++++++++++------- .../framework/lit/src/utils/range-manager.ts | 3 ++ 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/packages/blocks/src/_common/components/rich-text/rich-text.ts b/packages/blocks/src/_common/components/rich-text/rich-text.ts index 5cb10c8baff0..3400140e340c 100644 --- a/packages/blocks/src/_common/components/rich-text/rich-text.ts +++ b/packages/blocks/src/_common/components/rich-text/rich-text.ts @@ -367,8 +367,8 @@ export class RichText extends WithDisposable(ShadowlessElement) { .catch(console.error); } - override updated() { - if (this._inlineEditor) { + override updated(changedProperties: Map) { + if (this._inlineEditor && changedProperties.has('readonly')) { this._inlineEditor.setReadonly(this.readonly); } } diff --git a/packages/blocks/src/note-block/note-block.ts b/packages/blocks/src/note-block/note-block.ts index 906ad57bc849..88c386d85c25 100644 --- a/packages/blocks/src/note-block/note-block.ts +++ b/packages/blocks/src/note-block/note-block.ts @@ -1,5 +1,5 @@ /// -import { BlockElement, RangeManager } from '@blocksuite/lit'; +import { BlockElement } from '@blocksuite/lit'; import { css, html } from 'lit'; import { customElement } from 'lit/decorators.js'; @@ -26,8 +26,6 @@ export class NoteBlockComponent extends BlockElement< override connectedCallback() { super.connectedCallback(); - this.setAttribute(RangeManager.rangeSyncExcludeAttr, 'true'); - this.keymapController.bind(); } diff --git a/packages/framework/inline/src/services/range.ts b/packages/framework/inline/src/services/range.ts index fce4e1e3b529..99a840b2f24f 100644 --- a/packages/framework/inline/src/services/range.ts +++ b/packages/framework/inline/src/services/range.ts @@ -72,7 +72,10 @@ export class RangeService { if (this.editor.mounted) { // range change may happen before the editor is prepared await this.editor.waitForUpdate(); - this.editor.requestUpdate(false); + // improve performance + requestIdleCallback(() => { + this.editor.requestUpdate(false); + }); } if (!sync) { diff --git a/packages/framework/lit/src/utils/range-binding.ts b/packages/framework/lit/src/utils/range-binding.ts index 4e5307072338..212718bf7ba6 100644 --- a/packages/framework/lit/src/utils/range-binding.ts +++ b/packages/framework/lit/src/utils/range-binding.ts @@ -1,9 +1,9 @@ import type { BaseSelection, TextSelection } from '@blocksuite/block-std'; import { PathFinder } from '@blocksuite/block-std'; -import { assertExists } from '@blocksuite/global/utils'; +import { assertExists, throttle } from '@blocksuite/global/utils'; import { BlockElement } from '../element/block-element.js'; -import type { RangeManager } from './range-manager.js'; +import { RangeManager } from './range-manager.js'; /** * Two-way binding between native range and text selection @@ -28,9 +28,12 @@ export class RangeBinding { ); this.host.disposables.add( - this.host.event.add('selectionChange', () => { - this._onNativeSelectionChanged().catch(console.error); - }) + this.host.event.add( + 'selectionChange', + throttle(() => { + this._onNativeSelectionChanged().catch(console.error); + }, 10) + ) ); this.host.disposables.add( @@ -52,7 +55,7 @@ export class RangeBinding { } isComposing = false; - private _prevSelection: BaseSelection | null = null; + private _prevTextSelection: TextSelection | null = null; private _onStdSelectionChanged = (selections: BaseSelection[]) => { // wait for lit updated this.host.updateComplete @@ -63,14 +66,14 @@ export class RangeBinding { ) ?? null; const eq = - text && this._prevSelection - ? text.equals(this._prevSelection) - : text === this._prevSelection; + text && this._prevTextSelection + ? text.equals(this._prevTextSelection) + : text === this._prevTextSelection; if (eq) { return; } - this._prevSelection = text; + this._prevTextSelection = text; if (text) { this.rangeManager.syncTextSelectionToRange(text); } else { @@ -100,18 +103,27 @@ export class RangeBinding { Node.DOCUMENT_POSITION_PRECEDING); if (range) { + const el = + range.commonAncestorContainer instanceof Element + ? range.commonAncestorContainer + : range.commonAncestorContainer.parentElement; + if (!el) return; + const block = el.closest(`[${this.host.blockIdAttr}]`); + if (block?.getAttribute(RangeManager.rangeSyncExcludeAttr) === 'true') + return; + const inlineEditor = this.rangeManager.getClosestInlineEditor( range.commonAncestorContainer ); - if (inlineEditor && inlineEditor.isComposing) return; + if (inlineEditor?.isComposing) return; - this._prevSelection = this.rangeManager.rangeToTextSelection( + this._prevTextSelection = this.rangeManager.rangeToTextSelection( range, isRangeReversed ); this.rangeManager.syncRangeToTextSelection(range, isRangeReversed); } else { - this._prevSelection = null; + this._prevTextSelection = null; this.selectionManager.clear(['text']); } }; diff --git a/packages/framework/lit/src/utils/range-manager.ts b/packages/framework/lit/src/utils/range-manager.ts index 0015224b3cc3..6e52c2463104 100644 --- a/packages/framework/lit/src/utils/range-manager.ts +++ b/packages/framework/lit/src/utils/range-manager.ts @@ -35,6 +35,9 @@ export class RangeManager { if (topContenteditableElement instanceof HTMLElement) { topContenteditableElement.blur(); } + if (document.activeElement instanceof HTMLElement) { + document.activeElement.blur(); + } } set(range: Range) {