From fff4b2e0c1716d1feff7699d9181e88a041583d3 Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Thu, 14 Sep 2023 09:20:23 +0100 Subject: [PATCH] Use dispatchTransactions option when creating EditorView (#14743) Co-authored-by: Tim Down <158919+timdown@users.noreply.github.com> GitOrigin-RevId: ccc43ead570bdf96e47d1d08fc114ddce32d1293 --- .../components/codemirror-editor.tsx | 8 +-- .../js/infrastructure/cm6-performance.ts | 51 +++++++++++-------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/services/web/frontend/js/features/source-editor/components/codemirror-editor.tsx b/services/web/frontend/js/features/source-editor/components/codemirror-editor.tsx index 7f8680faed..e80f54cd48 100644 --- a/services/web/frontend/js/features/source-editor/components/codemirror-editor.tsx +++ b/services/web/frontend/js/features/source-editor/components/codemirror-editor.tsx @@ -41,13 +41,13 @@ function CodeMirrorEditor() { const view = new EditorView({ state, - dispatch: tr => { - timer.start(tr) - view.update([tr]) + dispatchTransactions: trs => { + timer.start(trs) + view.update(trs) if (isMounted.current) { setState(view.state) } - timer.end(tr, view) + timer.end(trs, view) }, }) viewRef.current = view diff --git a/services/web/frontend/js/infrastructure/cm6-performance.ts b/services/web/frontend/js/infrastructure/cm6-performance.ts index 2e9aa3a531..0b743c4f86 100644 --- a/services/web/frontend/js/infrastructure/cm6-performance.ts +++ b/services/web/frontend/js/infrastructure/cm6-performance.ts @@ -81,8 +81,8 @@ function isKeypress(userEventType: string | undefined) { } export function dispatchTimer(): { - start: (tr: Transaction) => void - end: (tr: Transaction, view: EditorView) => void + start: (trs: readonly Transaction[]) => void + end: (trs: readonly Transaction[], view: EditorView) => void } { if (!performanceOptionsSupport) { return { start: () => {}, end: () => {} } @@ -92,34 +92,45 @@ export function dispatchTimer(): { let keypressesSinceDomUpdateCount = 0 const unpaintedKeypressStartTimes: number[] = [] - const start = (tr: Transaction) => { - const userEventType = tr.annotation(Transaction.userEvent) + const start = (trs: readonly Transaction[]) => { + const keypressStart = performance.now() - if (isKeypress(userEventType)) { - unpaintedKeypressStartTimes.push(performance.now()) - } + trs.forEach(tr => { + const userEventType = tr.annotation(Transaction.userEvent) + + if (isKeypress(userEventType)) { + unpaintedKeypressStartTimes.push(keypressStart) + } + }) performance.mark(TIMER_START_NAME) } - const end = (tr: Transaction, view: EditorView) => { + const end = (trs: readonly Transaction[], view: EditorView) => { performance.mark(TIMER_END_NAME) - const userEventType = tr.annotation(Transaction.userEvent) + let anyInputOrDelete = false - if (isInputOrDelete(userEventType)) { - ++userEventsSinceDomUpdateCount + trs.forEach(tr => { + const userEventType = tr.annotation(Transaction.userEvent) - if (isKeypress(userEventType)) { - ++keypressesSinceDomUpdateCount + if (isInputOrDelete(userEventType)) { + anyInputOrDelete = true + ++userEventsSinceDomUpdateCount + + if (isKeypress(userEventType)) { + ++keypressesSinceDomUpdateCount + } + + performance.measure(TIMER_MEASURE_NAME, { + start: TIMER_START_NAME, + end: TIMER_END_NAME, + detail: { userEventType, userEventsSinceDomUpdateCount }, + }) } + }) - performance.measure(TIMER_MEASURE_NAME, { - start: TIMER_START_NAME, - end: TIMER_END_NAME, - detail: { userEventType, userEventsSinceDomUpdateCount }, - }) - + if (anyInputOrDelete) { // The `key` property ensures that the measurement task is only run once // per measure phase view.requestMeasure({ @@ -144,7 +155,7 @@ export function dispatchTimer(): { }) } - latestDocLength = tr.state.doc.length + latestDocLength = trs[trs.length - 1].state.doc.length } return { start, end }