@grafana/scenes 6.40.0--canary.1280.18680778214.0 → 6.40.0--canary.1265.18710211578.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/esm/behaviors/SceneInteractionTracker.js.map +1 -1
  2. package/dist/esm/behaviors/SceneQueryController.js.map +1 -1
  3. package/dist/esm/components/SceneRefreshPicker.js +1 -1
  4. package/dist/esm/components/SceneRefreshPicker.js.map +1 -1
  5. package/dist/esm/components/SceneTimeRangeCompare.js +0 -2
  6. package/dist/esm/components/SceneTimeRangeCompare.js.map +1 -1
  7. package/dist/esm/components/VizPanel/VizPanel.js +26 -0
  8. package/dist/esm/components/VizPanel/VizPanel.js.map +1 -1
  9. package/dist/esm/components/VizPanel/VizPanelRenderer.js +18 -1
  10. package/dist/esm/components/VizPanel/VizPanelRenderer.js.map +1 -1
  11. package/dist/esm/core/SceneTimeRange.js +1 -1
  12. package/dist/esm/core/SceneTimeRange.js.map +1 -1
  13. package/dist/esm/index.js +5 -3
  14. package/dist/esm/index.js.map +1 -1
  15. package/dist/esm/{behaviors → performance}/LongFrameDetector.js +11 -11
  16. package/dist/esm/performance/LongFrameDetector.js.map +1 -0
  17. package/dist/esm/performance/PanelProfilingManager.js +65 -0
  18. package/dist/esm/performance/PanelProfilingManager.js.map +1 -0
  19. package/dist/esm/performance/ScenePerformanceTracker.js +78 -0
  20. package/dist/esm/performance/ScenePerformanceTracker.js.map +1 -0
  21. package/dist/esm/{behaviors → performance}/SceneRenderProfiler.js +87 -132
  22. package/dist/esm/performance/SceneRenderProfiler.js.map +1 -0
  23. package/dist/esm/performance/VizPanelRenderProfiler.js +316 -0
  24. package/dist/esm/performance/VizPanelRenderProfiler.js.map +1 -0
  25. package/dist/esm/performance/index.js +3 -0
  26. package/dist/esm/performance/index.js.map +1 -0
  27. package/dist/esm/performance/interactionConstants.js +13 -0
  28. package/dist/esm/performance/interactionConstants.js.map +1 -0
  29. package/dist/esm/querying/SceneDataTransformer.js +57 -0
  30. package/dist/esm/querying/SceneDataTransformer.js.map +1 -1
  31. package/dist/esm/querying/SceneQueryRunner.js +11 -6
  32. package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
  33. package/dist/esm/querying/registerQueryWithController.js +39 -2
  34. package/dist/esm/querying/registerQueryWithController.js.map +1 -1
  35. package/dist/esm/services/UniqueUrlKeyMapper.js +0 -1
  36. package/dist/esm/services/UniqueUrlKeyMapper.js.map +1 -1
  37. package/dist/esm/services/UrlSyncManager.js +0 -1
  38. package/dist/esm/services/UrlSyncManager.js.map +1 -1
  39. package/dist/esm/utils/findPanelProfiler.js +18 -0
  40. package/dist/esm/utils/findPanelProfiler.js.map +1 -0
  41. package/dist/esm/utils/writePerformanceLog.js +12 -0
  42. package/dist/esm/utils/writePerformanceLog.js.map +1 -0
  43. package/dist/esm/utils/writeSceneLog.js +1 -10
  44. package/dist/esm/utils/writeSceneLog.js.map +1 -1
  45. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js +1 -1
  46. package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js.map +1 -1
  47. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +1 -1
  48. package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
  49. package/dist/esm/variables/components/VariableValueSelect.js +1 -1
  50. package/dist/esm/variables/components/VariableValueSelect.js.map +1 -1
  51. package/dist/esm/variables/groupby/GroupByVariable.js +1 -1
  52. package/dist/esm/variables/groupby/GroupByVariable.js.map +1 -1
  53. package/dist/esm/variables/variants/MultiValueVariable.js +1 -1
  54. package/dist/esm/variables/variants/MultiValueVariable.js.map +1 -1
  55. package/dist/esm/variables/variants/ScopesVariable.js +1 -1
  56. package/dist/esm/variables/variants/ScopesVariable.js.map +1 -1
  57. package/dist/index.d.ts +324 -95
  58. package/dist/index.js +6691 -6130
  59. package/dist/index.js.map +1 -1
  60. package/package.json +2 -2
  61. package/dist/esm/behaviors/LongFrameDetector.js.map +0 -1
  62. package/dist/esm/behaviors/SceneRenderProfiler.js.map +0 -1
@@ -1,4 +1,6 @@
1
- import { writeSceneLog, writeSceneLogStyled } from '../utils/writeSceneLog.js';
1
+ import { writePerformanceLog } from '../utils/writePerformanceLog.js';
2
+ import { generateOperationId, getScenePerformanceTracker } from './ScenePerformanceTracker.js';
3
+ import { PanelProfilingManager } from './PanelProfilingManager.js';
2
4
  import { LongFrameDetector } from './LongFrameDetector.js';
3
5
 
4
6
  var __typeError = (msg) => {
@@ -16,17 +18,20 @@ var __privateWrapper = (obj, member, setter, getter) => ({
16
18
  return __privateGet(obj, member, getter);
17
19
  }
18
20
  });
19
- var _profileInProgress, _interactionInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans, _longFrameDetector, _longFramesCount, _longFramesTotalTime, _visibilityChangeHandler, _onInteractionComplete;
21
+ var _profileInProgress, _interactionInProgress, _profileStartTs, _trailAnimationFrameId, _currentOperationId, _recordedTrailingSpans, _longFrameDetector, _longFramesCount, _longFramesTotalTime, _visibilityChangeHandler, _onInteractionComplete;
20
22
  const POST_STORM_WINDOW = 2e3;
21
23
  const DEFAULT_LONG_FRAME_THRESHOLD = 30;
22
24
  class SceneRenderProfiler {
23
- constructor(queryController) {
24
- this.queryController = queryController;
25
+ constructor(panelProfilingConfig) {
25
26
  __privateAdd(this, _profileInProgress, null);
26
27
  __privateAdd(this, _interactionInProgress, null);
27
28
  __privateAdd(this, _profileStartTs, null);
28
29
  __privateAdd(this, _trailAnimationFrameId, null);
29
- // Will keep measured lengths trailing frames
30
+ // Generic metadata for observer notifications
31
+ this.metadata = {};
32
+ // Operation ID for correlating dashboard interaction events
33
+ __privateAdd(this, _currentOperationId);
34
+ // Trailing frame measurements
30
35
  __privateAdd(this, _recordedTrailingSpans, []);
31
36
  // Long frame tracking
32
37
  __privateAdd(this, _longFrameDetector);
@@ -35,7 +40,6 @@ class SceneRenderProfiler {
35
40
  __privateAdd(this, _visibilityChangeHandler, null);
36
41
  __privateAdd(this, _onInteractionComplete, null);
37
42
  this.measureTrailingFrames = (measurementStartTs, lastFrameTime, profileStartTs) => {
38
- var _a, _b, _c, _d;
39
43
  const currentFrameTime = performance.now();
40
44
  const frameLength = currentFrameTime - lastFrameTime;
41
45
  __privateGet(this, _recordedTrailingSpans).push(frameLength);
@@ -48,108 +52,73 @@ class SceneRenderProfiler {
48
52
  } else {
49
53
  const slowFrames = processRecordedSpans(__privateGet(this, _recordedTrailingSpans));
50
54
  const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);
51
- writeSceneLog(
52
- "SceneRenderProfiler",
53
- `Profile tail recorded - Slow frames: ${slowFramesTime.toFixed(1)}ms (${slowFrames.length} frames)`
55
+ writePerformanceLog(
56
+ "SRP",
57
+ "Profile tail recorded, slow frames duration:",
58
+ slowFramesTime,
59
+ slowFrames,
60
+ __privateGet(this, _profileInProgress)
54
61
  );
55
- writeSceneLog("", ` \u251C\u2500 Origin: ${((_a = __privateGet(this, _profileInProgress)) == null ? void 0 : _a.origin) || "unknown"}`);
56
- writeSceneLog("", ` \u2514\u2500 Crumbs:`, ((_b = __privateGet(this, _profileInProgress)) == null ? void 0 : _b.crumbs) || []);
57
62
  __privateSet(this, _recordedTrailingSpans, []);
58
63
  const profileDuration = measurementStartTs - profileStartTs;
59
- if (typeof performance !== "undefined" && performance.mark) {
60
- const profileName = ((_c = __privateGet(this, _profileInProgress)) == null ? void 0 : _c.origin) || "unknown";
61
- const totalTime = profileDuration + slowFramesTime;
62
- performance.mark(`Dashboard Profile End: ${profileName}`);
63
- const startMarkName = `Dashboard Profile Start: ${profileName}`;
64
- try {
65
- performance.measure(
66
- `Dashboard Profile: ${profileName} (${totalTime.toFixed(1)}ms)`,
67
- startMarkName,
68
- `Dashboard Profile End: ${profileName}`
69
- );
70
- } catch (e) {
71
- performance.mark(`Dashboard Profile Complete: ${profileName} (${totalTime.toFixed(1)}ms)`);
72
- }
73
- if (slowFrames.length > 0) {
74
- const slowFramesMarkName = `Slow Frames Summary: ${slowFrames.length} frames (${slowFramesTime.toFixed(
75
- 1
76
- )}ms)`;
77
- performance.mark(slowFramesMarkName);
78
- slowFrames.forEach((frameTime, index) => {
79
- if (frameTime > 16) {
80
- try {
81
- const frameStartTime = __privateGet(this, _profileStartTs) + profileDuration + (index > 0 ? slowFrames.slice(0, index).reduce((sum, t) => sum + t, 0) : 0);
82
- const frameId = `slow-frame-${index}`;
83
- const frameStartMark = `${frameId}-start`;
84
- const frameEndMark = `${frameId}-end`;
85
- performance.mark(frameStartMark, { startTime: frameStartTime });
86
- performance.mark(frameEndMark, { startTime: frameStartTime + frameTime });
87
- performance.measure(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`, frameStartMark, frameEndMark);
88
- } catch (e) {
89
- performance.mark(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`);
90
- }
91
- }
92
- });
93
- }
94
- }
95
- const completionTimestamp = performance.now();
96
- writeSceneLog("SceneRenderProfiler", "Profile completed");
97
- writeSceneLog("", ` \u251C\u2500 Timestamp: ${completionTimestamp.toFixed(1)}ms`);
98
- writeSceneLog("", ` \u251C\u2500 Total time: ${(profileDuration + slowFramesTime).toFixed(1)}ms`);
99
- writeSceneLog("", ` \u251C\u2500 Slow frames: ${slowFramesTime}ms (${slowFrames.length} frames)`);
100
- writeSceneLog("", ` \u2514\u2500 Long frames: ${__privateGet(this, _longFramesTotalTime)}ms (${__privateGet(this, _longFramesCount)} frames)`);
101
- __privateGet(this, _longFrameDetector).stop();
102
- writeSceneLogStyled(
103
- "SceneRenderProfiler",
104
- `Stopped long frame detection - profile complete at ${completionTimestamp.toFixed(1)}ms`,
105
- "color: #00CC00; font-weight: bold;"
64
+ const slowFrameSummary = slowFrames.length > 0 ? `${slowFramesTime.toFixed(1)}ms slow frames[tail recording] (${slowFrames.length}) \u26A0\uFE0F` : `${slowFramesTime.toFixed(1)}ms slow frames[tail recording] (${slowFrames.length})`;
65
+ const longFrameSummary = __privateGet(this, _longFramesCount) > 0 ? `${__privateGet(this, _longFramesTotalTime).toFixed(1)}ms long frames[LoAF] (${__privateGet(this, _longFramesCount)}) \u26A0\uFE0F` : `${__privateGet(this, _longFramesTotalTime).toFixed(1)}ms long frames[LoAF] (${__privateGet(this, _longFramesCount)})`;
66
+ writePerformanceLog(
67
+ "SRP",
68
+ `[PROFILER] Complete: ${(profileDuration + slowFramesTime).toFixed(
69
+ 1
70
+ )}ms total | ${slowFrameSummary} | ${longFrameSummary}`
106
71
  );
72
+ __privateGet(this, _longFrameDetector).stop();
107
73
  __privateSet(this, _trailAnimationFrameId, null);
108
74
  const profileEndTs = profileStartTs + profileDuration + slowFramesTime;
109
75
  if (!__privateGet(this, _profileInProgress)) {
110
76
  return;
111
77
  }
112
- performance.measure(`DashboardInteraction ${__privateGet(this, _profileInProgress).origin}`, {
113
- start: profileStartTs,
114
- end: profileEndTs
115
- });
116
78
  const networkDuration = captureNetwork(profileStartTs, profileEndTs);
117
- if (((_d = this.queryController) == null ? void 0 : _d.state.onProfileComplete) && __privateGet(this, _profileInProgress)) {
118
- this.queryController.state.onProfileComplete({
119
- origin: __privateGet(this, _profileInProgress).origin,
120
- crumbs: __privateGet(this, _profileInProgress).crumbs,
79
+ if (__privateGet(this, _profileInProgress)) {
80
+ const dashboardData = {
81
+ operationId: __privateGet(this, _currentOperationId) || generateOperationId("dashboard-fallback"),
82
+ interactionType: __privateGet(this, _profileInProgress).origin,
83
+ timestamp: profileEndTs,
121
84
  duration: profileDuration + slowFramesTime,
122
85
  networkDuration,
123
- startTs: profileStartTs,
124
- endTs: profileEndTs,
125
86
  longFramesCount: __privateGet(this, _longFramesCount),
126
87
  longFramesTotalTime: __privateGet(this, _longFramesTotalTime),
127
- // @ts-ignore
128
- jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,
129
- // @ts-ignore
130
- usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,
131
- // @ts-ignore
132
- totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0
133
- });
88
+ metadata: this.metadata
89
+ };
90
+ const tracker = getScenePerformanceTracker();
91
+ tracker.notifyDashboardInteractionComplete(dashboardData);
134
92
  __privateSet(this, _profileInProgress, null);
135
93
  __privateSet(this, _trailAnimationFrameId, null);
136
94
  }
137
- if (window.__runs) {
138
- window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}
139
- `;
140
- } else {
141
- window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}
142
- `;
143
- }
144
95
  }
145
96
  };
146
97
  __privateSet(this, _longFrameDetector, new LongFrameDetector());
147
98
  this.setupVisibilityChangeHandler();
148
99
  __privateSet(this, _interactionInProgress, null);
100
+ if (panelProfilingConfig) {
101
+ this._panelProfilingManager = new PanelProfilingManager(panelProfilingConfig);
102
+ }
103
+ }
104
+ /** Set generic metadata for observer notifications */
105
+ setMetadata(metadata) {
106
+ this.metadata = { ...metadata };
149
107
  }
150
108
  setQueryController(queryController) {
151
109
  this.queryController = queryController;
152
110
  }
111
+ /** Attach panel profiling to a scene object */
112
+ attachPanelProfiling(sceneObject) {
113
+ var _a;
114
+ (_a = this._panelProfilingManager) == null ? void 0 : _a.attachToScene(sceneObject);
115
+ }
116
+ /** Attach profiler to a specific panel */
117
+ attachProfilerToPanel(panel) {
118
+ var _a;
119
+ writePerformanceLog("SRP", "Attaching profiler to panel", panel.state.key);
120
+ (_a = this._panelProfilingManager) == null ? void 0 : _a.attachProfilerToPanel(panel);
121
+ }
153
122
  setInteractionCompleteHandler(handler) {
154
123
  __privateSet(this, _onInteractionComplete, handler != null ? handler : null);
155
124
  }
@@ -159,7 +128,7 @@ class SceneRenderProfiler {
159
128
  }
160
129
  __privateSet(this, _visibilityChangeHandler, () => {
161
130
  if (document.hidden && __privateGet(this, _profileInProgress)) {
162
- writeSceneLog("SceneRenderProfiler", "Tab became inactive, cancelling profile");
131
+ writePerformanceLog("SRP", "Tab became inactive, cancelling profile");
163
132
  this.cancelProfile();
164
133
  }
165
134
  });
@@ -168,16 +137,18 @@ class SceneRenderProfiler {
168
137
  }
169
138
  }
170
139
  cleanup() {
140
+ var _a;
171
141
  if (__privateGet(this, _visibilityChangeHandler) && typeof document !== "undefined") {
172
142
  document.removeEventListener("visibilitychange", __privateGet(this, _visibilityChangeHandler));
173
143
  __privateSet(this, _visibilityChangeHandler, null);
174
144
  }
175
145
  __privateGet(this, _longFrameDetector).stop();
176
146
  this.cancelProfile();
147
+ (_a = this._panelProfilingManager) == null ? void 0 : _a.cleanup();
177
148
  }
178
149
  startProfile(name) {
179
150
  if (document.hidden) {
180
- writeSceneLog("SceneRenderProfiler", "Tab is inactive, skipping profile", name);
151
+ writePerformanceLog("SRP", "Tab is inactive, skipping profile", name);
181
152
  return;
182
153
  }
183
154
  if (__privateGet(this, _profileInProgress)) {
@@ -193,14 +164,14 @@ class SceneRenderProfiler {
193
164
  }
194
165
  startInteraction(interaction) {
195
166
  if (__privateGet(this, _interactionInProgress)) {
196
- writeSceneLog("profile", "Cancelled interaction:", __privateGet(this, _interactionInProgress));
167
+ writePerformanceLog("SRP", "Cancelled interaction:", __privateGet(this, _interactionInProgress));
197
168
  __privateSet(this, _interactionInProgress, null);
198
169
  }
199
170
  __privateSet(this, _interactionInProgress, {
200
171
  interaction,
201
172
  startTs: performance.now()
202
173
  });
203
- writeSceneLog("SceneRenderProfiler", "Started interaction:", interaction);
174
+ writePerformanceLog("SRP", "Started interaction:", interaction);
204
175
  }
205
176
  stopInteraction() {
206
177
  if (!__privateGet(this, _interactionInProgress)) {
@@ -209,11 +180,10 @@ class SceneRenderProfiler {
209
180
  const endTs = performance.now();
210
181
  const interactionDuration = endTs - __privateGet(this, _interactionInProgress).startTs;
211
182
  const networkDuration = captureNetwork(__privateGet(this, _interactionInProgress).startTs, endTs);
212
- writeSceneLog("SceneRenderProfiler", "Completed interaction:");
213
- writeSceneLog("", ` \u251C\u2500 Total time: ${interactionDuration.toFixed(1)}ms`);
214
- writeSceneLog("", ` \u251C\u2500 Network duration: ${networkDuration.toFixed(1)}ms`);
215
- writeSceneLog("", ` \u251C\u2500 StartTs: ${__privateGet(this, _interactionInProgress).startTs.toFixed(1)}ms`);
216
- writeSceneLog("", ` \u2514\u2500 EndTs: ${endTs.toFixed(1)}ms`);
183
+ writePerformanceLog(
184
+ "SRP",
185
+ `[INTERACTION] Complete: ${interactionDuration.toFixed(1)}ms total | ${networkDuration.toFixed(1)}ms network`
186
+ );
217
187
  if (__privateGet(this, _onInteractionComplete) && __privateGet(this, _profileInProgress)) {
218
188
  __privateGet(this, _onInteractionComplete).call(this, {
219
189
  origin: __privateGet(this, _interactionInProgress).interaction,
@@ -241,32 +211,24 @@ class SceneRenderProfiler {
241
211
  return (_b = (_a = __privateGet(this, _interactionInProgress)) == null ? void 0 : _a.interaction) != null ? _b : null;
242
212
  }
243
213
  /**
244
- * Starts a new profile for performance measurement.
245
- *
246
- * @param name - The origin/trigger of the profile (e.g., 'time_range_change', 'variable_value_changed')
247
- * @param force - Whether this is a "forced" profile (true) or "clean" profile (false)
248
- * - "forced": Started by canceling an existing profile that was recording trailing frames
249
- * This happens when a new user interaction occurs before the previous one
250
- * finished measuring its performance impact
251
- * - "clean": Started when no profile is currently active
214
+ * Start new performance profile
215
+ * @param name - Profile trigger (e.g., 'time_range_change')
216
+ * @param force - True if canceling existing profile, false if starting clean
252
217
  */
253
218
  _startNewProfile(name, force = false) {
254
- var _a;
219
+ const profileType = force ? "forced" : "clean";
220
+ writePerformanceLog("SRP", `[PROFILER] ${name} started (${profileType})`);
255
221
  __privateSet(this, _profileInProgress, { origin: name, crumbs: [] });
256
222
  __privateSet(this, _profileStartTs, performance.now());
257
223
  __privateSet(this, _longFramesCount, 0);
258
224
  __privateSet(this, _longFramesTotalTime, 0);
259
- if (typeof performance !== "undefined" && performance.mark) {
260
- const markName = `Dashboard Profile Start: ${name}`;
261
- performance.mark(markName);
262
- }
263
- writeSceneLogStyled(
264
- "SceneRenderProfiler",
265
- `Profile started[${force ? "forced" : "clean"}]`,
266
- "color: #FFCC00; font-weight: bold;"
267
- );
268
- writeSceneLog("", ` \u251C\u2500 Origin: ${((_a = __privateGet(this, _profileInProgress)) == null ? void 0 : _a.origin) || "unknown"}`);
269
- writeSceneLog("", ` \u2514\u2500 Timestamp: ${__privateGet(this, _profileStartTs).toFixed(1)}ms`);
225
+ __privateSet(this, _currentOperationId, generateOperationId("dashboard"));
226
+ getScenePerformanceTracker().notifyDashboardInteractionStart({
227
+ operationId: __privateGet(this, _currentOperationId),
228
+ interactionType: name,
229
+ timestamp: __privateGet(this, _profileStartTs),
230
+ metadata: this.metadata
231
+ });
270
232
  __privateGet(this, _longFrameDetector).start((event) => {
271
233
  if (!__privateGet(this, _profileInProgress) || !__privateGet(this, _profileStartTs)) {
272
234
  return;
@@ -285,12 +247,9 @@ class SceneRenderProfiler {
285
247
  }
286
248
  tryCompletingProfile() {
287
249
  var _a;
288
- if (!__privateGet(this, _profileInProgress)) {
289
- return;
290
- }
291
- writeSceneLog("SceneRenderProfiler", "Trying to complete profile", __privateGet(this, _profileInProgress));
250
+ writePerformanceLog("SRP", "Trying to complete profile", __privateGet(this, _profileInProgress));
292
251
  if (((_a = this.queryController) == null ? void 0 : _a.runningQueriesCount()) === 0 && __privateGet(this, _profileInProgress)) {
293
- writeSceneLog("SceneRenderProfiler", "All queries completed, starting tail measurement");
252
+ writePerformanceLog("SRP", "All queries completed, stopping profile");
294
253
  this.recordProfileTail(performance.now(), __privateGet(this, _profileStartTs));
295
254
  }
296
255
  }
@@ -301,20 +260,19 @@ class SceneRenderProfiler {
301
260
  if (__privateGet(this, _trailAnimationFrameId)) {
302
261
  cancelAnimationFrame(__privateGet(this, _trailAnimationFrameId));
303
262
  __privateSet(this, _trailAnimationFrameId, null);
304
- writeSceneLog("SceneRenderProfiler", "Cancelled recording frames, new profile started");
263
+ writePerformanceLog("SRP", "Cancelled recording frames, new profile started");
305
264
  }
306
265
  }
307
- // cancel profile
308
266
  cancelProfile() {
309
267
  if (__privateGet(this, _profileInProgress)) {
310
- writeSceneLog("SceneRenderProfiler", "Cancelling profile", __privateGet(this, _profileInProgress));
268
+ writePerformanceLog("SRP", "Cancelling profile", __privateGet(this, _profileInProgress));
311
269
  __privateSet(this, _profileInProgress, null);
312
270
  if (__privateGet(this, _trailAnimationFrameId)) {
313
271
  cancelAnimationFrame(__privateGet(this, _trailAnimationFrameId));
314
272
  __privateSet(this, _trailAnimationFrameId, null);
315
273
  }
316
274
  __privateGet(this, _longFrameDetector).stop();
317
- writeSceneLog("SceneRenderProfiler", "Stopped long frame detection - profile cancelled");
275
+ writePerformanceLog("SRP", "Stopped long frame detection - profile cancelled");
318
276
  __privateSet(this, _recordedTrailingSpans, []);
319
277
  __privateSet(this, _longFramesCount, 0);
320
278
  __privateSet(this, _longFramesTotalTime, 0);
@@ -322,7 +280,13 @@ class SceneRenderProfiler {
322
280
  }
323
281
  addCrumb(crumb) {
324
282
  if (__privateGet(this, _profileInProgress)) {
325
- writeSceneLog("SceneRenderProfiler", "Adding crumb:", crumb);
283
+ getScenePerformanceTracker().notifyDashboardInteractionMilestone({
284
+ operationId: generateOperationId("dashboard-milestone"),
285
+ interactionType: __privateGet(this, _profileInProgress).origin,
286
+ timestamp: performance.now(),
287
+ milestone: crumb,
288
+ metadata: this.metadata
289
+ });
326
290
  __privateGet(this, _profileInProgress).crumbs.push(crumb);
327
291
  }
328
292
  }
@@ -331,6 +295,7 @@ _profileInProgress = new WeakMap();
331
295
  _interactionInProgress = new WeakMap();
332
296
  _profileStartTs = new WeakMap();
333
297
  _trailAnimationFrameId = new WeakMap();
298
+ _currentOperationId = new WeakMap();
334
299
  _recordedTrailingSpans = new WeakMap();
335
300
  _longFrameDetector = new WeakMap();
336
301
  _longFramesCount = new WeakMap();
@@ -379,16 +344,6 @@ function calculateNetworkTime(requests) {
379
344
  totalNetworkTime += currentEnd - currentStart;
380
345
  return totalNetworkTime;
381
346
  }
382
- const REFRESH_INTERACTION = "refresh";
383
- const TIME_RANGE_CHANGE_INTERACTION = "time_range_change";
384
- const FILTER_REMOVED_INTERACTION = "filter_removed";
385
- const FILTER_CHANGED_INTERACTION = "filter_changed";
386
- const FILTER_RESTORED_INTERACTION = "filter_restored";
387
- const VARIABLE_VALUE_CHANGED_INTERACTION = "variable_value_changed";
388
- const SCOPES_CHANGED_INTERACTION = "scopes_changed";
389
- const ADHOC_KEYS_DROPDOWN_INTERACTION = "adhoc_keys_dropdown";
390
- const ADHOC_VALUES_DROPDOWN_INTERACTION = "adhoc_values_dropdown";
391
- const GROUPBY_DIMENSIONS_INTERACTION = "groupby_dimensions";
392
347
 
393
- export { ADHOC_KEYS_DROPDOWN_INTERACTION, ADHOC_VALUES_DROPDOWN_INTERACTION, FILTER_CHANGED_INTERACTION, FILTER_REMOVED_INTERACTION, FILTER_RESTORED_INTERACTION, GROUPBY_DIMENSIONS_INTERACTION, REFRESH_INTERACTION, SCOPES_CHANGED_INTERACTION, SceneRenderProfiler, TIME_RANGE_CHANGE_INTERACTION, VARIABLE_VALUE_CHANGED_INTERACTION, calculateNetworkTime, captureNetwork, processRecordedSpans };
348
+ export { SceneRenderProfiler, calculateNetworkTime, captureNetwork, processRecordedSpans };
394
349
  //# sourceMappingURL=SceneRenderProfiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/performance/SceneRenderProfiler.ts"],"sourcesContent":["import { writePerformanceLog } from '../utils/writePerformanceLog';\nimport { SceneQueryControllerLike, LongFrameEvent, SceneComponentInteractionEvent } from '../behaviors/types';\nimport {\n getScenePerformanceTracker,\n generateOperationId,\n DashboardInteractionCompleteData,\n} from './ScenePerformanceTracker';\nimport { PanelProfilingManager, PanelProfilingConfig } from './PanelProfilingManager';\nimport { SceneObject } from '../core/types';\nimport { VizPanel } from '../components/VizPanel/VizPanel';\nimport { LongFrameDetector } from './LongFrameDetector';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst DEFAULT_LONG_FRAME_THRESHOLD = 30; // Threshold for tail recording slow frames\n\n/**\n * SceneRenderProfiler tracks dashboard interaction performance including:\n * - Total interaction duration\n * - Network time\n * - Long frame detection (50ms threshold) during interaction using LoAF API (default) or manual tracking (fallback)\n * - Slow frame detection (30ms threshold) for tail recording after interaction\n *\n * Long frame detection during interaction:\n * - 50ms threshold aligned with LoAF API default\n * - LoAF API preferred (Chrome 123+) with manual fallback\n * - Provides script attribution when using LoAF API\n *\n * Slow frame detection for tail recording:\n * - 30ms threshold for post-interaction monitoring\n * - Manual frame timing measurement\n * - Captures rendering delays after user interaction completes\n */\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n origin: string; // Profile trigger (e.g., 'time_range_change')\n crumbs: string[];\n } | null = null;\n\n #interactionInProgress: {\n interaction: string;\n startTs: number;\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Generic metadata for observer notifications\n private metadata: Record<string, unknown> = {};\n\n // Operation ID for correlating dashboard interaction events\n #currentOperationId?: string;\n\n // Trailing frame measurements\n #recordedTrailingSpans: number[] = [];\n\n // Long frame tracking\n #longFrameDetector: LongFrameDetector;\n #longFramesCount = 0;\n #longFramesTotalTime = 0;\n\n #visibilityChangeHandler: (() => void) | null = null;\n #onInteractionComplete: ((event: SceneComponentInteractionEvent) => void) | null = null;\n\n // Panel profiling composition\n private _panelProfilingManager?: PanelProfilingManager;\n\n // Query controller for monitoring query completion\n private queryController?: SceneQueryControllerLike;\n\n public constructor(panelProfilingConfig?: PanelProfilingConfig) {\n this.#longFrameDetector = new LongFrameDetector();\n this.setupVisibilityChangeHandler();\n this.#interactionInProgress = null;\n\n // Compose with panel profiling manager if provided\n if (panelProfilingConfig) {\n this._panelProfilingManager = new PanelProfilingManager(panelProfilingConfig);\n }\n }\n\n /** Set generic metadata for observer notifications */\n public setMetadata(metadata: Record<string, unknown>) {\n this.metadata = { ...metadata };\n }\n\n public setQueryController(queryController: SceneQueryControllerLike) {\n this.queryController = queryController;\n }\n\n /** Attach panel profiling to a scene object */\n public attachPanelProfiling(sceneObject: SceneObject) {\n this._panelProfilingManager?.attachToScene(sceneObject);\n }\n\n /** Attach profiler to a specific panel */\n public attachProfilerToPanel(panel: VizPanel): void {\n writePerformanceLog('SRP', 'Attaching profiler to panel', panel.state.key);\n this._panelProfilingManager?.attachProfilerToPanel(panel);\n }\n\n public setInteractionCompleteHandler(handler?: (event: SceneComponentInteractionEvent) => void) {\n this.#onInteractionComplete = handler ?? null;\n }\n\n private setupVisibilityChangeHandler() {\n if (this.#visibilityChangeHandler) {\n return;\n }\n\n // Cancel profiling when tab becomes inactive\n this.#visibilityChangeHandler = () => {\n if (document.hidden && this.#profileInProgress) {\n writePerformanceLog('SRP', 'Tab became inactive, cancelling profile');\n this.cancelProfile();\n }\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', this.#visibilityChangeHandler);\n }\n }\n\n public cleanup() {\n if (this.#visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.#visibilityChangeHandler);\n this.#visibilityChangeHandler = null;\n }\n\n // Cleanup long frame tracking\n this.#longFrameDetector.stop();\n\n // Cancel any ongoing profiling\n this.cancelProfile();\n\n // Cleanup composed panel profiling manager\n this._panelProfilingManager?.cleanup();\n }\n\n public startProfile(name: string) {\n // Skip profiling if tab is inactive\n if (document.hidden) {\n writePerformanceLog('SRP', 'Tab is inactive, skipping profile', name);\n return;\n }\n\n if (this.#profileInProgress) {\n if (this.#trailAnimationFrameId) {\n this.cancelProfile();\n this._startNewProfile(name, true);\n } else {\n this.addCrumb(name);\n }\n } else {\n this._startNewProfile(name);\n }\n }\n\n public startInteraction(interaction: string) {\n // Cancel any existing interaction recording\n if (this.#interactionInProgress) {\n writePerformanceLog('SRP', 'Cancelled interaction:', this.#interactionInProgress);\n this.#interactionInProgress = null;\n }\n\n this.#interactionInProgress = {\n interaction,\n startTs: performance.now(),\n };\n\n writePerformanceLog('SRP', 'Started interaction:', interaction);\n }\n\n public stopInteraction() {\n if (!this.#interactionInProgress) {\n return;\n }\n\n const endTs = performance.now();\n const interactionDuration = endTs - this.#interactionInProgress.startTs;\n\n // Capture network requests that occurred during the interaction\n const networkDuration = captureNetwork(this.#interactionInProgress.startTs, endTs);\n\n writePerformanceLog(\n 'SRP',\n `[INTERACTION] Complete: ${interactionDuration.toFixed(1)}ms total | ${networkDuration.toFixed(1)}ms network`\n );\n\n if (this.#onInteractionComplete && this.#profileInProgress) {\n this.#onInteractionComplete({\n origin: this.#interactionInProgress.interaction,\n duration: interactionDuration,\n networkDuration,\n startTs: this.#interactionInProgress.startTs,\n endTs,\n });\n }\n\n // Create performance marks for browser dev tools\n performance.mark(`${this.#interactionInProgress.interaction}_start`, {\n startTime: this.#interactionInProgress.startTs,\n });\n performance.mark(`${this.#interactionInProgress.interaction}_end`, {\n startTime: endTs,\n });\n performance.measure(\n `Interaction_${this.#interactionInProgress.interaction}`,\n `${this.#interactionInProgress.interaction}_start`,\n `${this.#interactionInProgress.interaction}_end`\n );\n\n this.#interactionInProgress = null;\n }\n\n public getCurrentInteraction(): string | null {\n return this.#interactionInProgress?.interaction ?? null;\n }\n\n /**\n * Start new performance profile\n * @param name - Profile trigger (e.g., 'time_range_change')\n * @param force - True if canceling existing profile, false if starting clean\n */\n private _startNewProfile(name: string, force = false) {\n const profileType = force ? 'forced' : 'clean';\n writePerformanceLog('SRP', `[PROFILER] ${name} started (${profileType})`);\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n\n this.#currentOperationId = generateOperationId('dashboard');\n getScenePerformanceTracker().notifyDashboardInteractionStart({\n operationId: this.#currentOperationId,\n interactionType: name,\n timestamp: this.#profileStartTs,\n metadata: this.metadata,\n });\n\n // Start long frame detection with callback\n this.#longFrameDetector.start((event: LongFrameEvent) => {\n // Only record long frames during active profiling\n if (!this.#profileInProgress || !this.#profileStartTs) {\n return;\n }\n\n // Only record frames that occur after profile started\n if (event.timestamp < this.#profileStartTs) {\n return;\n }\n\n this.#longFramesCount++;\n this.#longFramesTotalTime += event.duration;\n });\n }\n\n private recordProfileTail(measurementStartTime: number, profileStartTs: number) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTime, measurementStartTime, profileStartTs)\n );\n }\n\n private measureTrailingFrames = (measurementStartTs: number, lastFrameTime: number, profileStartTs: number) => {\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - lastFrameTime;\n\n this.#recordedTrailingSpans.push(frameLength);\n\n if (currentFrameTime - measurementStartTs! < POST_STORM_WINDOW) {\n if (this.#profileInProgress) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTs, currentFrameTime, profileStartTs)\n );\n }\n } else {\n const slowFrames = processRecordedSpans(this.#recordedTrailingSpans);\n const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);\n\n writePerformanceLog(\n 'SRP',\n 'Profile tail recorded, slow frames duration:',\n slowFramesTime,\n slowFrames,\n this.#profileInProgress\n );\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n const slowFrameSummary =\n slowFrames.length > 0\n ? `${slowFramesTime.toFixed(1)}ms slow frames[tail recording] (${slowFrames.length}) ⚠️`\n : `${slowFramesTime.toFixed(1)}ms slow frames[tail recording] (${slowFrames.length})`;\n\n const longFrameSummary =\n this.#longFramesCount > 0\n ? `${this.#longFramesTotalTime.toFixed(1)}ms long frames[LoAF] (${this.#longFramesCount}) ⚠️`\n : `${this.#longFramesTotalTime.toFixed(1)}ms long frames[LoAF] (${this.#longFramesCount})`;\n\n writePerformanceLog(\n 'SRP',\n `[PROFILER] Complete: ${(profileDuration + slowFramesTime).toFixed(\n 1\n )}ms total | ${slowFrameSummary} | ${longFrameSummary}`\n );\n this.#longFrameDetector.stop();\n\n this.#trailAnimationFrameId = null;\n\n const profileEndTs = profileStartTs + profileDuration + slowFramesTime;\n\n // Guard against race condition where profile might be cancelled during execution\n if (!this.#profileInProgress) {\n return;\n }\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.#profileInProgress) {\n // Notify performance observers of dashboard interaction completion\n const dashboardData: DashboardInteractionCompleteData = {\n operationId: this.#currentOperationId || generateOperationId('dashboard-fallback'),\n interactionType: this.#profileInProgress.origin,\n timestamp: profileEndTs,\n duration: profileDuration + slowFramesTime,\n networkDuration: networkDuration,\n longFramesCount: this.#longFramesCount,\n longFramesTotalTime: this.#longFramesTotalTime,\n metadata: this.metadata,\n };\n\n const tracker = getScenePerformanceTracker();\n tracker.notifyDashboardInteractionComplete(dashboardData);\n\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n }\n }\n };\n\n public tryCompletingProfile() {\n writePerformanceLog('SRP', 'Trying to complete profile', this.#profileInProgress);\n if (this.queryController?.runningQueriesCount() === 0 && this.#profileInProgress) {\n writePerformanceLog('SRP', 'All queries completed, stopping profile');\n this.recordProfileTail(performance.now(), this.#profileStartTs!);\n }\n }\n\n public isTailRecording() {\n return Boolean(this.#trailAnimationFrameId);\n }\n\n public cancelTailRecording() {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n writePerformanceLog('SRP', 'Cancelled recording frames, new profile started');\n }\n }\n\n public cancelProfile() {\n if (this.#profileInProgress) {\n writePerformanceLog('SRP', 'Cancelling profile', this.#profileInProgress);\n\n this.#profileInProgress = null;\n // Cancel any pending animation frame to prevent accessing null profileInProgress\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n }\n // Stop long frame tracking\n this.#longFrameDetector.stop();\n writePerformanceLog('SRP', 'Stopped long frame detection - profile cancelled');\n // Reset recorded spans to ensure complete cleanup\n this.#recordedTrailingSpans = [];\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n // Notify performance observers of milestone\n getScenePerformanceTracker().notifyDashboardInteractionMilestone({\n operationId: generateOperationId('dashboard-milestone'),\n interactionType: this.#profileInProgress.origin,\n timestamp: performance.now(),\n milestone: crumb,\n metadata: this.metadata,\n });\n this.#profileInProgress.crumbs.push(crumb);\n }\n }\n}\n\nexport function processRecordedSpans(spans: number[]) {\n // identify last span in spans that's bigger than default threshold\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > DEFAULT_LONG_FRAME_THRESHOLD) {\n return spans.slice(0, i + 1);\n }\n }\n return [spans[0]];\n}\n\nexport function captureNetwork(startTs: number, endTs: number) {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n performance.clearResourceTimings();\n // Only include network entries that both started AND ended within the time window\n const networkEntries = entries.filter(\n (entry) =>\n entry.startTime >= startTs &&\n entry.startTime <= endTs &&\n entry.responseEnd >= startTs &&\n entry.responseEnd <= endTs\n );\n for (const entry of networkEntries) {\n performance.measure('Network entry ' + entry.name, {\n start: entry.startTime,\n end: entry.responseEnd,\n });\n }\n\n return calculateNetworkTime(networkEntries);\n}\n\n// Will calculate total time spent on Network\nexport function calculateNetworkTime(requests: PerformanceResourceTiming[]): number {\n if (requests.length === 0) {\n return 0;\n }\n\n // Step 1: Sort the requests by startTs\n requests.sort((a, b) => a.startTime - b.startTime);\n\n // Step 2: Initialize variables\n let totalNetworkTime = 0;\n let currentStart = requests[0].startTime;\n let currentEnd = requests[0].responseEnd;\n\n // Step 3: Iterate through the sorted list and merge overlapping intervals\n for (let i = 1; i < requests.length; i++) {\n if (requests[i].startTime <= currentEnd) {\n // Overlapping intervals, merge them\n currentEnd = Math.max(currentEnd, requests[i].responseEnd);\n } else {\n // Non-overlapping interval, add the duration to total time\n totalNetworkTime += currentEnd - currentStart;\n\n // Update current interval\n currentStart = requests[i].startTime;\n currentEnd = requests[i].responseEnd;\n }\n }\n\n // Step 4: Add the last interval\n totalNetworkTime += currentEnd - currentStart;\n\n return totalNetworkTime;\n}\n"],"names":[],"mappings":"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"}