From 3523289e988b51cd49f0ed665938c129274ef90c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 24 Oct 2024 11:05:13 +0200 Subject: [PATCH] Dashboards: Fixes performance issue expanding a row (#95311) * DashboardScene: Optimize change detection * Remove arg * remove console log --- .../saving/DashboardSceneChangeTracker.ts | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/public/app/features/dashboard-scene/saving/DashboardSceneChangeTracker.ts b/public/app/features/dashboard-scene/saving/DashboardSceneChangeTracker.ts index d7b5cf74ff8..c9f9abea55c 100644 --- a/public/app/features/dashboard-scene/saving/DashboardSceneChangeTracker.ts +++ b/public/app/features/dashboard-scene/saving/DashboardSceneChangeTracker.ts @@ -1,3 +1,4 @@ +import { debounce } from 'lodash'; import { Unsubscribable } from 'rxjs'; import { @@ -120,12 +121,6 @@ export class DashboardSceneChangeTracker { return false; } - private onStateChanged(event: SceneObjectStateChangedEvent) { - if (DashboardSceneChangeTracker.isUpdatingPersistedState(event)) { - this.detectSaveModelChanges(); - } - } - private detectSaveModelChanges() { const changedDashboard = transformSceneToSaveModel(this._dashboard); const initialDashboard = this._dashboard.getInitialSaveModel(); @@ -165,13 +160,20 @@ export class DashboardSceneChangeTracker { if (!this._changesWorker) { this.init(); } + this._changesWorker!.onmessage = (e: MessageEvent) => { this.updateIsDirty(e.data); }; + const performSaveModelDiff = getChangeTrackerDebouncer(this.detectSaveModelChanges.bind(this)); + this._changeTrackerSub = this._dashboard.subscribeToEvent( SceneObjectStateChangedEvent, - this.onStateChanged.bind(this) + (event: SceneObjectStateChangedEvent) => { + if (DashboardSceneChangeTracker.isUpdatingPersistedState(event)) { + performSaveModelDiff(); + } + } ); } @@ -185,3 +187,14 @@ export class DashboardSceneChangeTracker { this._changesWorker = undefined; } } + +/** + * The debouncer makes unit tests slower and more complex so turning it off for unit tests + */ +function getChangeTrackerDebouncer(fn: () => void) { + if (process.env.NODE_ENV === 'test') { + return fn; + } + + return debounce(fn, 250); +}