@grafana/scenes 6.33.1--canary.1235.17401475625.0 → 6.34.0--canary.1221.17416885253.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.
@@ -1,5 +1,4 @@
1
- import { writeSceneLog, writeSceneLogStyled } from '../utils/writeSceneLog.js';
2
- import { LongFrameDetector } from './LongFrameDetector.js';
1
+ import { writeSceneLog } from '../utils/writeSceneLog.js';
3
2
 
4
3
  var __typeError = (msg) => {
5
4
  throw TypeError(msg);
@@ -8,17 +7,9 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
8
7
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
8
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10
9
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
11
- var __privateWrapper = (obj, member, setter, getter) => ({
12
- set _(value) {
13
- __privateSet(obj, member, value);
14
- },
15
- get _() {
16
- return __privateGet(obj, member, getter);
17
- }
18
- });
19
- var _profileInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans, _longFrameDetector, _longFramesCount, _longFramesTotalTime, _visibilityChangeHandler;
10
+ var _profileInProgress, _profileStartTs, _trailAnimationFrameId, _recordedTrailingSpans, _visibilityChangeHandler;
20
11
  const POST_STORM_WINDOW = 2e3;
21
- const DEFAULT_LONG_FRAME_THRESHOLD = 30;
12
+ const SPAN_THRESHOLD = 30;
22
13
  const TAB_INACTIVE_THRESHOLD = 1e3;
23
14
  class SceneRenderProfiler {
24
15
  constructor(queryController) {
@@ -28,13 +19,9 @@ class SceneRenderProfiler {
28
19
  __privateAdd(this, _trailAnimationFrameId, null);
29
20
  // Will keep measured lengths trailing frames
30
21
  __privateAdd(this, _recordedTrailingSpans, []);
31
- // Long frame tracking
32
- __privateAdd(this, _longFrameDetector);
33
- __privateAdd(this, _longFramesCount, 0);
34
- __privateAdd(this, _longFramesTotalTime, 0);
35
22
  __privateAdd(this, _visibilityChangeHandler, null);
36
23
  this.measureTrailingFrames = (measurementStartTs, lastFrameTime, profileStartTs) => {
37
- var _a, _b, _c, _d;
24
+ var _a;
38
25
  const currentFrameTime = performance.now();
39
26
  const frameLength = currentFrameTime - lastFrameTime;
40
27
  if (frameLength > TAB_INACTIVE_THRESHOLD) {
@@ -53,60 +40,18 @@ class SceneRenderProfiler {
53
40
  const slowFrames = processRecordedSpans(__privateGet(this, _recordedTrailingSpans));
54
41
  const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);
55
42
  writeSceneLog(
56
- "SceneRenderProfiler",
57
- `Profile tail recorded - Slow frames: ${slowFramesTime.toFixed(1)}ms (${slowFrames.length} frames)`
43
+ this.constructor.name,
44
+ "Profile tail recorded, slow frames duration:",
45
+ slowFramesTime,
46
+ slowFrames,
47
+ __privateGet(this, _profileInProgress)
58
48
  );
59
- writeSceneLog("", ` \u251C\u2500 Origin: ${((_a = __privateGet(this, _profileInProgress)) == null ? void 0 : _a.origin) || "unknown"}`);
60
- writeSceneLog("", ` \u2514\u2500 Crumbs:`, ((_b = __privateGet(this, _profileInProgress)) == null ? void 0 : _b.crumbs) || []);
61
49
  __privateSet(this, _recordedTrailingSpans, []);
62
50
  const profileDuration = measurementStartTs - profileStartTs;
63
- if (typeof performance !== "undefined" && performance.mark) {
64
- const profileName = ((_c = __privateGet(this, _profileInProgress)) == null ? void 0 : _c.origin) || "unknown";
65
- const totalTime = profileDuration + slowFramesTime;
66
- performance.mark(`Dashboard Profile End: ${profileName}`);
67
- const startMarkName = `Dashboard Profile Start: ${profileName}`;
68
- try {
69
- performance.measure(
70
- `Dashboard Profile: ${profileName} (${totalTime.toFixed(1)}ms)`,
71
- startMarkName,
72
- `Dashboard Profile End: ${profileName}`
73
- );
74
- } catch (e) {
75
- performance.mark(`Dashboard Profile Complete: ${profileName} (${totalTime.toFixed(1)}ms)`);
76
- }
77
- if (slowFrames.length > 0) {
78
- const slowFramesMarkName = `Slow Frames Summary: ${slowFrames.length} frames (${slowFramesTime.toFixed(
79
- 1
80
- )}ms)`;
81
- performance.mark(slowFramesMarkName);
82
- slowFrames.forEach((frameTime, index) => {
83
- if (frameTime > 16) {
84
- try {
85
- const frameStartTime = __privateGet(this, _profileStartTs) + profileDuration + (index > 0 ? slowFrames.slice(0, index).reduce((sum, t) => sum + t, 0) : 0);
86
- const frameId = `slow-frame-${index}`;
87
- const frameStartMark = `${frameId}-start`;
88
- const frameEndMark = `${frameId}-end`;
89
- performance.mark(frameStartMark, { startTime: frameStartTime });
90
- performance.mark(frameEndMark, { startTime: frameStartTime + frameTime });
91
- performance.measure(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`, frameStartMark, frameEndMark);
92
- } catch (e) {
93
- performance.mark(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`);
94
- }
95
- }
96
- });
97
- }
98
- }
99
- const completionTimestamp = performance.now();
100
- writeSceneLog("SceneRenderProfiler", "Profile completed");
101
- writeSceneLog("", ` \u251C\u2500 Timestamp: ${completionTimestamp.toFixed(1)}ms`);
102
- writeSceneLog("", ` \u251C\u2500 Total time: ${(profileDuration + slowFramesTime).toFixed(1)}ms`);
103
- writeSceneLog("", ` \u251C\u2500 Slow frames: ${slowFramesTime}ms (${slowFrames.length} frames)`);
104
- writeSceneLog("", ` \u2514\u2500 Long frames: ${__privateGet(this, _longFramesTotalTime)}ms (${__privateGet(this, _longFramesCount)} frames)`);
105
- __privateGet(this, _longFrameDetector).stop();
106
- writeSceneLogStyled(
107
- "SceneRenderProfiler",
108
- `Stopped long frame detection - profile complete at ${completionTimestamp.toFixed(1)}ms`,
109
- "color: #00CC00; font-weight: bold;"
51
+ writeSceneLog(
52
+ this.constructor.name,
53
+ "Stoped recording, total measured time (network included):",
54
+ profileDuration + slowFramesTime
110
55
  );
111
56
  __privateSet(this, _trailAnimationFrameId, null);
112
57
  const profileEndTs = profileStartTs + profileDuration + slowFramesTime;
@@ -118,7 +63,7 @@ class SceneRenderProfiler {
118
63
  end: profileEndTs
119
64
  });
120
65
  const networkDuration = captureNetwork(profileStartTs, profileEndTs);
121
- if (((_d = this.queryController) == null ? void 0 : _d.state.onProfileComplete) && __privateGet(this, _profileInProgress)) {
66
+ if (((_a = this.queryController) == null ? void 0 : _a.state.onProfileComplete) && __privateGet(this, _profileInProgress)) {
122
67
  this.queryController.state.onProfileComplete({
123
68
  origin: __privateGet(this, _profileInProgress).origin,
124
69
  crumbs: __privateGet(this, _profileInProgress).crumbs,
@@ -126,8 +71,6 @@ class SceneRenderProfiler {
126
71
  networkDuration,
127
72
  startTs: profileStartTs,
128
73
  endTs: profileEndTs,
129
- longFramesCount: __privateGet(this, _longFramesCount),
130
- longFramesTotalTime: __privateGet(this, _longFramesTotalTime),
131
74
  // @ts-ignore
132
75
  jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,
133
76
  // @ts-ignore
@@ -147,7 +90,6 @@ class SceneRenderProfiler {
147
90
  }
148
91
  }
149
92
  };
150
- __privateSet(this, _longFrameDetector, new LongFrameDetector());
151
93
  this.setupVisibilityChangeHandler();
152
94
  }
153
95
  setQueryController(queryController) {
@@ -172,7 +114,6 @@ class SceneRenderProfiler {
172
114
  document.removeEventListener("visibilitychange", __privateGet(this, _visibilityChangeHandler));
173
115
  __privateSet(this, _visibilityChangeHandler, null);
174
116
  }
175
- __privateGet(this, _longFrameDetector).stop();
176
117
  this.cancelProfile();
177
118
  }
178
119
  startProfile(name) {
@@ -202,32 +143,14 @@ class SceneRenderProfiler {
202
143
  * - "clean": Started when no profile is currently active
203
144
  */
204
145
  _startNewProfile(name, force = false) {
205
- var _a;
206
146
  __privateSet(this, _profileInProgress, { origin: name, crumbs: [] });
207
147
  __privateSet(this, _profileStartTs, performance.now());
208
- __privateSet(this, _longFramesCount, 0);
209
- __privateSet(this, _longFramesTotalTime, 0);
210
- if (typeof performance !== "undefined" && performance.mark) {
211
- const markName = `Dashboard Profile Start: ${name}`;
212
- performance.mark(markName);
213
- }
214
- writeSceneLogStyled(
148
+ writeSceneLog(
215
149
  "SceneRenderProfiler",
216
150
  `Profile started[${force ? "forced" : "clean"}]`,
217
- "color: #FFCC00; font-weight: bold;"
151
+ __privateGet(this, _profileInProgress),
152
+ __privateGet(this, _profileStartTs)
218
153
  );
219
- writeSceneLog("", ` \u251C\u2500 Origin: ${((_a = __privateGet(this, _profileInProgress)) == null ? void 0 : _a.origin) || "unknown"}`);
220
- writeSceneLog("", ` \u2514\u2500 Timestamp: ${__privateGet(this, _profileStartTs).toFixed(1)}ms`);
221
- __privateGet(this, _longFrameDetector).start((event) => {
222
- if (!__privateGet(this, _profileInProgress) || !__privateGet(this, _profileStartTs)) {
223
- return;
224
- }
225
- if (event.timestamp < __privateGet(this, _profileStartTs)) {
226
- return;
227
- }
228
- __privateWrapper(this, _longFramesCount)._++;
229
- __privateSet(this, _longFramesTotalTime, __privateGet(this, _longFramesTotalTime) + event.duration);
230
- });
231
154
  }
232
155
  recordProfileTail(measurementStartTime, profileStartTs) {
233
156
  __privateSet(this, _trailAnimationFrameId, requestAnimationFrame(
@@ -238,7 +161,7 @@ class SceneRenderProfiler {
238
161
  var _a;
239
162
  writeSceneLog("SceneRenderProfiler", "Trying to complete profile", __privateGet(this, _profileInProgress));
240
163
  if (((_a = this.queryController) == null ? void 0 : _a.runningQueriesCount()) === 0 && __privateGet(this, _profileInProgress)) {
241
- writeSceneLog("SceneRenderProfiler", "All queries completed, starting tail measurement");
164
+ writeSceneLog("SceneRenderProfiler", "All queries completed, stopping profile");
242
165
  this.recordProfileTail(performance.now(), __privateGet(this, _profileStartTs));
243
166
  }
244
167
  }
@@ -261,11 +184,7 @@ class SceneRenderProfiler {
261
184
  cancelAnimationFrame(__privateGet(this, _trailAnimationFrameId));
262
185
  __privateSet(this, _trailAnimationFrameId, null);
263
186
  }
264
- __privateGet(this, _longFrameDetector).stop();
265
- writeSceneLog("SceneRenderProfiler", "Stopped long frame detection - profile cancelled");
266
187
  __privateSet(this, _recordedTrailingSpans, []);
267
- __privateSet(this, _longFramesCount, 0);
268
- __privateSet(this, _longFramesTotalTime, 0);
269
188
  }
270
189
  }
271
190
  addCrumb(crumb) {
@@ -279,13 +198,10 @@ _profileInProgress = new WeakMap();
279
198
  _profileStartTs = new WeakMap();
280
199
  _trailAnimationFrameId = new WeakMap();
281
200
  _recordedTrailingSpans = new WeakMap();
282
- _longFrameDetector = new WeakMap();
283
- _longFramesCount = new WeakMap();
284
- _longFramesTotalTime = new WeakMap();
285
201
  _visibilityChangeHandler = new WeakMap();
286
202
  function processRecordedSpans(spans) {
287
203
  for (let i = spans.length - 1; i >= 0; i--) {
288
- if (spans[i] > DEFAULT_LONG_FRAME_THRESHOLD) {
204
+ if (spans[i] > SPAN_THRESHOLD) {
289
205
  return spans.slice(0, i + 1);
290
206
  }
291
207
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writeSceneLog, writeSceneLogStyled } from '../utils/writeSceneLog';\nimport { SceneQueryControllerLike, LongFrameEvent } from './types';\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\nconst TAB_INACTIVE_THRESHOLD = 1000; // Tab inactive threshold in ms\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 // Profile origin, i.e. scene refresh picker\n origin: string;\n crumbs: string[];\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Will keep measured lengths trailing frames\n #recordedTrailingSpans: number[] = [];\n\n // Long frame tracking\n #longFrameDetector: LongFrameDetector;\n #longFramesCount = 0;\n #longFramesTotalTime = 0;\n\n #visibilityChangeHandler: (() => void) | null = null;\n\n public constructor(private queryController?: SceneQueryControllerLike) {\n this.#longFrameDetector = new LongFrameDetector();\n this.setupVisibilityChangeHandler();\n }\n\n public setQueryController(queryController: SceneQueryControllerLike) {\n this.queryController = queryController;\n }\n\n private setupVisibilityChangeHandler() {\n // Ensure event listener is only added once\n if (this.#visibilityChangeHandler) {\n return;\n }\n\n // Handle tab switching with Page Visibility API\n this.#visibilityChangeHandler = () => {\n if (document.hidden && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', '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 // Remove event listener to prevent memory leaks\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\n public startProfile(name: string) {\n // Only start profile if tab is active. This makes sure we don't start a profile when i.e. someone opens a dashboard in a new tab\n // and doesn't interact with it.\n if (document.hidden) {\n writeSceneLog('SceneRenderProfiler', '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 /**\n * Starts a new profile for performance measurement.\n *\n * @param name - The origin/trigger of the profile (e.g., 'time_range_change', 'variable_value_changed')\n * @param force - Whether this is a \"forced\" profile (true) or \"clean\" profile (false)\n * - \"forced\": Started by canceling an existing profile that was recording trailing frames\n * This happens when a new user interaction occurs before the previous one\n * finished measuring its performance impact\n * - \"clean\": Started when no profile is currently active\n */\n private _startNewProfile(name: string, force = false) {\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n\n // Add performance mark for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark) {\n const markName = `Dashboard Profile Start: ${name}`;\n performance.mark(markName);\n }\n\n // Log profile start in structured format\n writeSceneLogStyled(\n 'SceneRenderProfiler',\n `Profile started[${force ? 'forced' : 'clean'}]`,\n 'color: #FFCC00; font-weight: bold;'\n );\n writeSceneLog('', ` ├─ Origin: ${this.#profileInProgress?.origin || 'unknown'}`);\n writeSceneLog('', ` └─ Timestamp: ${this.#profileStartTs.toFixed(1)}ms`);\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 // Fallback: Detect if tab was inactive (frame longer than reasonable threshold)\n // This serves as backup to Page Visibility API in case the event wasn't triggered\n if (frameLength > TAB_INACTIVE_THRESHOLD) {\n writeSceneLog('SceneRenderProfiler', 'Tab was inactive, cancelling profile measurement');\n this.cancelProfile();\n return;\n }\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 // Log tail recording in structured format\n writeSceneLog(\n 'SceneRenderProfiler',\n `Profile tail recorded - Slow frames: ${slowFramesTime.toFixed(1)}ms (${slowFrames.length} frames)`\n );\n writeSceneLog('', ` ├─ Origin: ${this.#profileInProgress?.origin || 'unknown'}`);\n writeSceneLog('', ` └─ Crumbs:`, this.#profileInProgress?.crumbs || []);\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n // Add performance marks for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark) {\n const profileName = this.#profileInProgress?.origin || 'unknown';\n const totalTime = profileDuration + slowFramesTime;\n\n // Mark profile completion\n performance.mark(`Dashboard Profile End: ${profileName}`);\n\n // Add measure from start to end if possible\n const startMarkName = `Dashboard Profile Start: ${profileName}`;\n try {\n performance.measure(\n `Dashboard Profile: ${profileName} (${totalTime.toFixed(1)}ms)`,\n startMarkName,\n `Dashboard Profile End: ${profileName}`\n );\n } catch {\n // Start mark might not exist, create a simple end mark\n performance.mark(`Dashboard Profile Complete: ${profileName} (${totalTime.toFixed(1)}ms)`);\n }\n\n // Add measurements for slow frame details if significant\n if (slowFrames.length > 0) {\n const slowFramesMarkName = `Slow Frames Summary: ${slowFrames.length} frames (${slowFramesTime.toFixed(\n 1\n )}ms)`;\n performance.mark(slowFramesMarkName);\n\n // Create individual measurements for each slow frame during tail\n slowFrames.forEach((frameTime, index) => {\n if (frameTime > 16) {\n // Only measure frames slower than 16ms (60fps)\n try {\n const frameStartTime =\n this.#profileStartTs! +\n profileDuration +\n (index > 0 ? slowFrames.slice(0, index).reduce((sum, t) => sum + t, 0) : 0);\n const frameId = `slow-frame-${index}`;\n const frameStartMark = `${frameId}-start`;\n const frameEndMark = `${frameId}-end`;\n\n performance.mark(frameStartMark, { startTime: frameStartTime });\n performance.mark(frameEndMark, { startTime: frameStartTime + frameTime });\n performance.measure(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`, frameStartMark, frameEndMark);\n } catch {\n // Fallback if startTime not supported\n performance.mark(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`);\n }\n }\n });\n }\n }\n\n // Log performance summary in a structured format\n const completionTimestamp = performance.now();\n writeSceneLog('SceneRenderProfiler', 'Profile completed');\n writeSceneLog('', ` ├─ Timestamp: ${completionTimestamp.toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Total time: ${(profileDuration + slowFramesTime).toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Slow frames: ${slowFramesTime}ms (${slowFrames.length} frames)`);\n writeSceneLog('', ` └─ Long frames: ${this.#longFramesTotalTime}ms (${this.#longFramesCount} frames)`);\n\n // Stop long frame detection now that the profile is complete\n this.#longFrameDetector.stop();\n writeSceneLogStyled(\n 'SceneRenderProfiler',\n `Stopped long frame detection - profile complete at ${completionTimestamp.toFixed(1)}ms`,\n 'color: #00CC00; font-weight: bold;'\n );\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 performance.measure(`DashboardInteraction ${this.#profileInProgress.origin}`, {\n start: profileStartTs,\n end: profileEndTs,\n });\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.queryController?.state.onProfileComplete && this.#profileInProgress) {\n this.queryController.state.onProfileComplete({\n origin: this.#profileInProgress.origin,\n crumbs: this.#profileInProgress.crumbs,\n duration: profileDuration + slowFramesTime,\n networkDuration,\n startTs: profileStartTs,\n endTs: profileEndTs,\n longFramesCount: this.#longFramesCount,\n longFramesTotalTime: this.#longFramesTotalTime,\n // @ts-ignore\n jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,\n // @ts-ignore\n usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,\n // @ts-ignore\n totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0,\n });\n\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n }\n // @ts-ignore\n if (window.__runs) {\n // @ts-ignore\n window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n } else {\n // @ts-ignore\n window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n }\n }\n };\n\n public tryCompletingProfile() {\n writeSceneLog('SceneRenderProfiler', 'Trying to complete profile', this.#profileInProgress);\n if (this.queryController?.runningQueriesCount() === 0 && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'All queries completed, starting tail measurement');\n // Note: Long frame detector continues running during tail measurement\n // It will be stopped when the profile completely finishes\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 writeSceneLog('SceneRenderProfiler', 'Cancelled recording frames, new profile started');\n }\n }\n\n // cancel profile\n public cancelProfile() {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Cancelling profile', this.#profileInProgress);\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 writeSceneLog('SceneRenderProfiler', '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 writeSceneLog('SceneRenderProfiler', 'Adding crumb:', crumb);\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\nexport const REFRESH_INTERACTION = 'refresh';\nexport const TIME_RANGE_CHANGE_INTERACTION = 'time_range_change';\nexport const FILTER_ADDED_INTERACTION = 'filter_added';\nexport const FILTER_REMOVED_INTERACTION = 'filter_removed';\nexport const FILTER_CHANGED_INTERACTION = 'filter_changed';\nexport const FILTER_RESTORED_INTERACTION = 'filter_restored';\nexport const VARIABLE_VALUE_CHANGED_INTERACTION = 'variable_value_changed';\nexport const SCOPES_CHANGED_INTERACTION = 'scopes_changed';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writeSceneLog } from '../utils/writeSceneLog';\nimport { SceneQueryControllerLike } from './types';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst SPAN_THRESHOLD = 30; // Frames longer than this will be considered slow\nconst TAB_INACTIVE_THRESHOLD = 1000; // Tab inactive threshold in ms\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n // Profile origin, i.e. scene refresh picker\n origin: string;\n crumbs: string[];\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Will keep measured lengths trailing frames\n #recordedTrailingSpans: number[] = [];\n\n #visibilityChangeHandler: (() => void) | null = null;\n\n public constructor(private queryController?: SceneQueryControllerLike) {\n this.setupVisibilityChangeHandler();\n }\n\n public setQueryController(queryController: SceneQueryControllerLike) {\n this.queryController = queryController;\n }\n\n private setupVisibilityChangeHandler() {\n // Ensure event listener is only added once\n if (this.#visibilityChangeHandler) {\n return;\n }\n\n // Handle tab switching with Page Visibility API\n this.#visibilityChangeHandler = () => {\n if (document.hidden && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', '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 // Remove event listener to prevent memory leaks\n if (this.#visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.#visibilityChangeHandler);\n this.#visibilityChangeHandler = null;\n }\n\n // Cancel any ongoing profiling\n this.cancelProfile();\n }\n\n public startProfile(name: string) {\n // Only start profile if tab is active. This makes sure we don't start a profile when i.e. someone opens a dashboard in a new tab\n // and doesn't interact with it.\n if (document.hidden) {\n writeSceneLog('SceneRenderProfiler', '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 /**\n * Starts a new profile for performance measurement.\n *\n * @param name - The origin/trigger of the profile (e.g., 'time_range_change', 'variable_value_changed')\n * @param force - Whether this is a \"forced\" profile (true) or \"clean\" profile (false)\n * - \"forced\": Started by canceling an existing profile that was recording trailing frames\n * This happens when a new user interaction occurs before the previous one\n * finished measuring its performance impact\n * - \"clean\": Started when no profile is currently active\n */\n private _startNewProfile(name: string, force = false) {\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n writeSceneLog(\n 'SceneRenderProfiler',\n `Profile started[${force ? 'forced' : 'clean'}]`,\n this.#profileInProgress,\n this.#profileStartTs\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 // Fallback: Detect if tab was inactive (frame longer than reasonable threshold)\n // This serves as backup to Page Visibility API in case the event wasn't triggered\n if (frameLength > TAB_INACTIVE_THRESHOLD) {\n writeSceneLog('SceneRenderProfiler', 'Tab was inactive, cancelling profile measurement');\n this.cancelProfile();\n return;\n }\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 writeSceneLog(\n this.constructor.name,\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 writeSceneLog(\n this.constructor.name,\n 'Stoped recording, total measured time (network included):',\n profileDuration + slowFramesTime\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 performance.measure(`DashboardInteraction ${this.#profileInProgress.origin}`, {\n start: profileStartTs,\n end: profileEndTs,\n });\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.queryController?.state.onProfileComplete && this.#profileInProgress) {\n this.queryController.state.onProfileComplete({\n origin: this.#profileInProgress.origin,\n crumbs: this.#profileInProgress.crumbs,\n duration: profileDuration + slowFramesTime,\n networkDuration,\n startTs: profileStartTs,\n endTs: profileEndTs,\n // @ts-ignore\n jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,\n // @ts-ignore\n usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,\n // @ts-ignore\n totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0,\n });\n\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n }\n // @ts-ignore\n if (window.__runs) {\n // @ts-ignore\n window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n } else {\n // @ts-ignore\n window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n }\n }\n };\n\n public tryCompletingProfile() {\n writeSceneLog('SceneRenderProfiler', 'Trying to complete profile', this.#profileInProgress);\n if (this.queryController?.runningQueriesCount() === 0 && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', '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 writeSceneLog('SceneRenderProfiler', 'Cancelled recording frames, new profile started');\n }\n }\n\n // cancel profile\n public cancelProfile() {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Cancelling profile', this.#profileInProgress);\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 // Reset recorded spans to ensure complete cleanup\n this.#recordedTrailingSpans = [];\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Adding crumb:', crumb);\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 SPAN_THRESHOLD\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > SPAN_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\nexport const REFRESH_INTERACTION = 'refresh';\nexport const TIME_RANGE_CHANGE_INTERACTION = 'time_range_change';\nexport const FILTER_ADDED_INTERACTION = 'filter_added';\nexport const FILTER_REMOVED_INTERACTION = 'filter_removed';\nexport const FILTER_CHANGED_INTERACTION = 'filter_changed';\nexport const FILTER_RESTORED_INTERACTION = 'filter_restored';\nexport const VARIABLE_VALUE_CHANGED_INTERACTION = 'variable_value_changed';\nexport const SCOPES_CHANGED_INTERACTION = 'scopes_changed';\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { t, Trans } from '@grafana/i18n';
2
- import { rangeUtil, dateTime, FieldType } from '@grafana/data';
3
- import { config } from '@grafana/runtime';
2
+ import { rangeUtil, dateTime } from '@grafana/data';
4
3
  import { useStyles2, ButtonGroup, ToolbarButton, Checkbox, ButtonSelect } from '@grafana/ui';
5
4
  import React from 'react';
6
5
  import { sceneGraph } from '../core/sceneGraph/index.js';
@@ -152,21 +151,6 @@ const timeShiftAlignmentProcessor = (primary, secondary) => {
152
151
  isTimeShiftQuery: true
153
152
  }
154
153
  };
155
- series.fields.forEach((field) => {
156
- if (field.type === FieldType.time) {
157
- field.values = field.values.map((v) => {
158
- return diff < 0 ? v - diff : v + diff;
159
- });
160
- }
161
- field.config = {
162
- ...field.config,
163
- color: {
164
- mode: "fixed",
165
- fixedColor: config.theme.palette.gray60
166
- }
167
- };
168
- return field;
169
- });
170
154
  });
171
155
  return of(secondary);
172
156
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SceneTimeRangeCompare.js","sources":["../../../src/components/SceneTimeRangeCompare.tsx"],"sourcesContent":["import { t, Trans } from '@grafana/i18n';\nimport { DataQueryRequest, DateTime, dateTime, FieldType, GrafanaTheme2, rangeUtil, TimeRange } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { ButtonGroup, ButtonSelect, Checkbox, ToolbarButton, useStyles2 } from '@grafana/ui';\nimport React from 'react';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { SceneComponentProps, SceneDataQuery, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { DataQueryExtended } from '../querying/SceneQueryRunner';\nimport { ExtraQueryDescriptor, ExtraQueryDataProcessor, ExtraQueryProvider } from '../querying/ExtraQueryProvider';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\nimport { getCompareSeriesRefId } from '../utils/getCompareSeriesRefId';\nimport { parseUrlParam } from '../utils/parseUrlParam';\nimport { css } from '@emotion/css';\nimport { of } from 'rxjs';\n\ninterface SceneTimeRangeCompareState extends SceneObjectState {\n compareWith?: string;\n compareOptions: Array<{ label: string; value: string }>;\n hideCheckbox?: boolean;\n}\n\nconst PREVIOUS_PERIOD_VALUE = '__previousPeriod';\nconst NO_PERIOD_VALUE = '__noPeriod';\n\nexport const PREVIOUS_PERIOD_COMPARE_OPTION = {\n label: 'Previous period',\n value: PREVIOUS_PERIOD_VALUE,\n};\n\nexport const NO_COMPARE_OPTION = {\n label: 'None',\n value: NO_PERIOD_VALUE,\n};\n\nexport const DEFAULT_COMPARE_OPTIONS = [\n { label: 'Day before', value: '24h' },\n { label: 'Week before', value: '1w' },\n { label: 'Month before', value: '1M' },\n];\n\nexport class SceneTimeRangeCompare\n extends SceneObjectBase<SceneTimeRangeCompareState>\n implements ExtraQueryProvider<SceneTimeRangeCompareState>\n{\n static Component = SceneTimeRangeCompareRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['compareWith'] });\n\n public constructor(state: Partial<SceneTimeRangeCompareState>) {\n super({ compareOptions: DEFAULT_COMPARE_OPTIONS, ...state });\n this.addActivationHandler(this._onActivate);\n }\n\n private _onActivate = () => {\n const sceneTimeRange = sceneGraph.getTimeRange(this);\n this.setState({ compareOptions: this.getCompareOptions(sceneTimeRange.state.value) });\n\n this._subs.add(\n sceneTimeRange.subscribeToState((timeRange) => {\n const compareOptions = this.getCompareOptions(timeRange.value);\n const stateUpdate: Partial<SceneTimeRangeCompareState> = { compareOptions };\n\n // if current compareWith is not applicable to the new time range, set it to previous period comparison\n if (Boolean(this.state.compareWith) && !compareOptions.find(({ value }) => value === this.state.compareWith)) {\n stateUpdate.compareWith = PREVIOUS_PERIOD_VALUE;\n }\n\n this.setState(stateUpdate);\n })\n );\n };\n\n public getCompareOptions = (timeRange: TimeRange) => {\n const diffDays = Math.ceil(timeRange.to.diff(timeRange.from));\n\n const matchIndex = DEFAULT_COMPARE_OPTIONS.findIndex(({ value }) => {\n const intervalInMs = rangeUtil.intervalToMs(value);\n return intervalInMs >= diffDays;\n });\n\n return [\n NO_COMPARE_OPTION,\n PREVIOUS_PERIOD_COMPARE_OPTION,\n ...DEFAULT_COMPARE_OPTIONS.slice(matchIndex).map(({ label, value }) => ({ label, value })),\n ];\n };\n\n public onCompareWithChanged = (compareWith: string) => {\n if (compareWith === NO_PERIOD_VALUE) {\n this.onClearCompare();\n } else {\n this.setState({ compareWith });\n }\n };\n\n public onClearCompare = () => {\n this.setState({ compareWith: undefined });\n };\n\n // Get a time shifted request to compare with the primary request.\n public getExtraQueries(request: DataQueryRequest): ExtraQueryDescriptor[] {\n const extraQueries: ExtraQueryDescriptor[] = [];\n const compareRange = this.getCompareTimeRange(request.range);\n if (!compareRange) {\n return extraQueries;\n }\n\n const targets = request.targets.filter((query: DataQueryExtended) => query.timeRangeCompare !== false);\n if (targets.length) {\n extraQueries.push({\n req: {\n ...request,\n targets,\n range: compareRange,\n },\n processor: timeShiftAlignmentProcessor,\n });\n }\n return extraQueries;\n }\n\n // The query runner should rerun the comparison query if the compareWith value has changed and there are queries that haven't opted out of TWC\n public shouldRerun(\n prev: SceneTimeRangeCompareState,\n next: SceneTimeRangeCompareState,\n queries: SceneDataQuery[]\n ): boolean {\n return (\n prev.compareWith !== next.compareWith && queries.find((query) => query.timeRangeCompare !== false) !== undefined\n );\n }\n\n public getCompareTimeRange(timeRange: TimeRange): TimeRange | undefined {\n let compareFrom: DateTime;\n let compareTo: DateTime;\n\n if (this.state.compareWith) {\n if (this.state.compareWith === PREVIOUS_PERIOD_VALUE) {\n const diffMs = timeRange.to.diff(timeRange.from);\n compareFrom = dateTime(timeRange.from!).subtract(diffMs);\n compareTo = dateTime(timeRange.to!).subtract(diffMs);\n } else {\n compareFrom = dateTime(timeRange.from!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n compareTo = dateTime(timeRange.to!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n }\n return {\n from: compareFrom,\n to: compareTo,\n raw: {\n from: compareFrom,\n to: compareTo,\n },\n };\n }\n\n return undefined;\n }\n\n public getUrlState(): SceneObjectUrlValues {\n return {\n compareWith: this.state.compareWith,\n };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n if (!values.compareWith) {\n return;\n }\n\n const compareWith = parseUrlParam(values.compareWith);\n\n if (compareWith) {\n const compareOptions = this.getCompareOptions(sceneGraph.getTimeRange(this).state.value);\n\n if (compareOptions.find(({ value }) => value === compareWith)) {\n this.setState({\n compareWith,\n });\n } else {\n this.setState({\n compareWith: '__previousPeriod',\n });\n }\n }\n }\n}\n\n// Processor function for use with time shifted comparison series.\n// This aligns the secondary series with the primary and adds custom\n// metadata and config to the secondary series' fields so that it is\n// rendered appropriately.\nconst timeShiftAlignmentProcessor: ExtraQueryDataProcessor = (primary, secondary) => {\n const diff = secondary.timeRange.from.diff(primary.timeRange.from);\n secondary.series.forEach((series) => {\n series.refId = getCompareSeriesRefId(series.refId || '');\n series.meta = {\n ...series.meta,\n // @ts-ignore Remove when https://github.com/grafana/grafana/pull/71129 is released\n timeCompare: {\n diffMs: diff,\n isTimeShiftQuery: true,\n },\n };\n series.fields.forEach((field) => {\n // Align compare series time stamps with reference series\n if (field.type === FieldType.time) {\n field.values = field.values.map((v) => {\n return diff < 0 ? v - diff : v + diff;\n });\n }\n\n field.config = {\n ...field.config,\n color: {\n mode: 'fixed',\n fixedColor: config.theme.palette.gray60,\n },\n };\n return field;\n });\n });\n return of(secondary);\n};\n\nfunction SceneTimeRangeCompareRenderer({ model }: SceneComponentProps<SceneTimeRangeCompare>) {\n const styles = useStyles2(getStyles);\n const { compareWith, compareOptions, hideCheckbox } = model.useState();\n\n const [previousCompare, setPreviousCompare] = React.useState(compareWith);\n const previousValue = compareOptions.find(({ value }) => value === previousCompare) ?? PREVIOUS_PERIOD_COMPARE_OPTION;\n\n const value = compareOptions.find(({ value }) => value === compareWith);\n const enabled = Boolean(value);\n\n const onClick = () => {\n if (enabled) {\n setPreviousCompare(compareWith);\n model.onClearCompare();\n } else if (!enabled) {\n model.onCompareWithChanged(previousValue.value);\n }\n };\n\n // When hideCheckbox is true, always show select and use NO_COMPARE_OPTION when no comparison is active\n const selectValue = hideCheckbox && !compareWith ? NO_COMPARE_OPTION : value;\n const showSelect = hideCheckbox || enabled;\n\n // Create display value with \"Comparison\" prefix when hideCheckbox is true\n const displayValue =\n hideCheckbox && selectValue\n ? {\n ...selectValue,\n label: `Comparison: ${selectValue.label}`,\n }\n : selectValue;\n\n return (\n <ButtonGroup>\n {!hideCheckbox && (\n <ToolbarButton\n variant=\"canvas\"\n tooltip={t(\n 'grafana-scenes.components.scene-time-range-compare-renderer.button-tooltip',\n 'Enable time frame comparison'\n )}\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onClick();\n }}\n >\n <Checkbox label=\" \" value={enabled} onClick={onClick} />\n <Trans i18nKey=\"grafana-scenes.components.scene-time-range-compare-renderer.button-label\">Comparison</Trans>\n </ToolbarButton>\n )}\n\n {showSelect ? (\n <ButtonSelect\n variant=\"canvas\"\n value={displayValue}\n options={compareOptions}\n onChange={(v) => {\n model.onCompareWithChanged(v.value!);\n }}\n />\n ) : (\n <ToolbarButton className={styles.previewButton} disabled variant=\"canvas\" isOpen={false}>\n {previousValue.label}\n </ToolbarButton>\n )}\n </ButtonGroup>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n previewButton: css({\n '&:disabled': {\n border: `1px solid ${theme.colors.secondary.border}`,\n color: theme.colors.text.disabled,\n opacity: 1,\n },\n }),\n };\n}\n"],"names":["value"],"mappings":"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"}
1
+ {"version":3,"file":"SceneTimeRangeCompare.js","sources":["../../../src/components/SceneTimeRangeCompare.tsx"],"sourcesContent":["import { t, Trans } from '@grafana/i18n';\nimport { DataQueryRequest, DateTime, dateTime, GrafanaTheme2, rangeUtil, TimeRange } from '@grafana/data';\nimport { ButtonGroup, ButtonSelect, Checkbox, ToolbarButton, useStyles2 } from '@grafana/ui';\nimport React from 'react';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { SceneComponentProps, SceneDataQuery, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { DataQueryExtended } from '../querying/SceneQueryRunner';\nimport { ExtraQueryDescriptor, ExtraQueryDataProcessor, ExtraQueryProvider } from '../querying/ExtraQueryProvider';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\nimport { getCompareSeriesRefId } from '../utils/getCompareSeriesRefId';\nimport { parseUrlParam } from '../utils/parseUrlParam';\nimport { css } from '@emotion/css';\nimport { of } from 'rxjs';\n\ninterface SceneTimeRangeCompareState extends SceneObjectState {\n compareWith?: string;\n compareOptions: Array<{ label: string; value: string }>;\n hideCheckbox?: boolean;\n}\n\nconst PREVIOUS_PERIOD_VALUE = '__previousPeriod';\nconst NO_PERIOD_VALUE = '__noPeriod';\n\nexport const PREVIOUS_PERIOD_COMPARE_OPTION = {\n label: 'Previous period',\n value: PREVIOUS_PERIOD_VALUE,\n};\n\nexport const NO_COMPARE_OPTION = {\n label: 'None',\n value: NO_PERIOD_VALUE,\n};\n\nexport const DEFAULT_COMPARE_OPTIONS = [\n { label: 'Day before', value: '24h' },\n { label: 'Week before', value: '1w' },\n { label: 'Month before', value: '1M' },\n];\n\nexport class SceneTimeRangeCompare\n extends SceneObjectBase<SceneTimeRangeCompareState>\n implements ExtraQueryProvider<SceneTimeRangeCompareState>\n{\n static Component = SceneTimeRangeCompareRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['compareWith'] });\n\n public constructor(state: Partial<SceneTimeRangeCompareState>) {\n super({ compareOptions: DEFAULT_COMPARE_OPTIONS, ...state });\n this.addActivationHandler(this._onActivate);\n }\n\n private _onActivate = () => {\n const sceneTimeRange = sceneGraph.getTimeRange(this);\n this.setState({ compareOptions: this.getCompareOptions(sceneTimeRange.state.value) });\n\n this._subs.add(\n sceneTimeRange.subscribeToState((timeRange) => {\n const compareOptions = this.getCompareOptions(timeRange.value);\n const stateUpdate: Partial<SceneTimeRangeCompareState> = { compareOptions };\n\n // if current compareWith is not applicable to the new time range, set it to previous period comparison\n if (Boolean(this.state.compareWith) && !compareOptions.find(({ value }) => value === this.state.compareWith)) {\n stateUpdate.compareWith = PREVIOUS_PERIOD_VALUE;\n }\n\n this.setState(stateUpdate);\n })\n );\n };\n\n public getCompareOptions = (timeRange: TimeRange) => {\n const diffDays = Math.ceil(timeRange.to.diff(timeRange.from));\n\n const matchIndex = DEFAULT_COMPARE_OPTIONS.findIndex(({ value }) => {\n const intervalInMs = rangeUtil.intervalToMs(value);\n return intervalInMs >= diffDays;\n });\n\n return [\n NO_COMPARE_OPTION,\n PREVIOUS_PERIOD_COMPARE_OPTION,\n ...DEFAULT_COMPARE_OPTIONS.slice(matchIndex).map(({ label, value }) => ({ label, value })),\n ];\n };\n\n public onCompareWithChanged = (compareWith: string) => {\n if (compareWith === NO_PERIOD_VALUE) {\n this.onClearCompare();\n } else {\n this.setState({ compareWith });\n }\n };\n\n public onClearCompare = () => {\n this.setState({ compareWith: undefined });\n };\n\n // Get a time shifted request to compare with the primary request.\n public getExtraQueries(request: DataQueryRequest): ExtraQueryDescriptor[] {\n const extraQueries: ExtraQueryDescriptor[] = [];\n const compareRange = this.getCompareTimeRange(request.range);\n if (!compareRange) {\n return extraQueries;\n }\n\n const targets = request.targets.filter((query: DataQueryExtended) => query.timeRangeCompare !== false);\n if (targets.length) {\n extraQueries.push({\n req: {\n ...request,\n targets,\n range: compareRange,\n },\n processor: timeShiftAlignmentProcessor,\n });\n }\n return extraQueries;\n }\n\n // The query runner should rerun the comparison query if the compareWith value has changed and there are queries that haven't opted out of TWC\n public shouldRerun(\n prev: SceneTimeRangeCompareState,\n next: SceneTimeRangeCompareState,\n queries: SceneDataQuery[]\n ): boolean {\n return (\n prev.compareWith !== next.compareWith && queries.find((query) => query.timeRangeCompare !== false) !== undefined\n );\n }\n\n public getCompareTimeRange(timeRange: TimeRange): TimeRange | undefined {\n let compareFrom: DateTime;\n let compareTo: DateTime;\n\n if (this.state.compareWith) {\n if (this.state.compareWith === PREVIOUS_PERIOD_VALUE) {\n const diffMs = timeRange.to.diff(timeRange.from);\n compareFrom = dateTime(timeRange.from!).subtract(diffMs);\n compareTo = dateTime(timeRange.to!).subtract(diffMs);\n } else {\n compareFrom = dateTime(timeRange.from!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n compareTo = dateTime(timeRange.to!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n }\n return {\n from: compareFrom,\n to: compareTo,\n raw: {\n from: compareFrom,\n to: compareTo,\n },\n };\n }\n\n return undefined;\n }\n\n public getUrlState(): SceneObjectUrlValues {\n return {\n compareWith: this.state.compareWith,\n };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n if (!values.compareWith) {\n return;\n }\n\n const compareWith = parseUrlParam(values.compareWith);\n\n if (compareWith) {\n const compareOptions = this.getCompareOptions(sceneGraph.getTimeRange(this).state.value);\n\n if (compareOptions.find(({ value }) => value === compareWith)) {\n this.setState({\n compareWith,\n });\n } else {\n this.setState({\n compareWith: '__previousPeriod',\n });\n }\n }\n }\n}\n\n// Processor function for use with time shifted comparison series.\n// This aligns the secondary series with the primary and adds custom\n// metadata and config to the secondary series' fields so that it is\n// rendered appropriately.\nconst timeShiftAlignmentProcessor: ExtraQueryDataProcessor = (primary, secondary) => {\n const diff = secondary.timeRange.from.diff(primary.timeRange.from);\n secondary.series.forEach((series) => {\n series.refId = getCompareSeriesRefId(series.refId || '');\n series.meta = {\n ...series.meta,\n // @ts-ignore Remove when https://github.com/grafana/grafana/pull/71129 is released\n timeCompare: {\n diffMs: diff,\n isTimeShiftQuery: true,\n },\n };\n });\n return of(secondary);\n};\n\nfunction SceneTimeRangeCompareRenderer({ model }: SceneComponentProps<SceneTimeRangeCompare>) {\n const styles = useStyles2(getStyles);\n const { compareWith, compareOptions, hideCheckbox } = model.useState();\n\n const [previousCompare, setPreviousCompare] = React.useState(compareWith);\n const previousValue = compareOptions.find(({ value }) => value === previousCompare) ?? PREVIOUS_PERIOD_COMPARE_OPTION;\n\n const value = compareOptions.find(({ value }) => value === compareWith);\n const enabled = Boolean(value);\n\n const onClick = () => {\n if (enabled) {\n setPreviousCompare(compareWith);\n model.onClearCompare();\n } else if (!enabled) {\n model.onCompareWithChanged(previousValue.value);\n }\n };\n\n // When hideCheckbox is true, always show select and use NO_COMPARE_OPTION when no comparison is active\n const selectValue = hideCheckbox && !compareWith ? NO_COMPARE_OPTION : value;\n const showSelect = hideCheckbox || enabled;\n\n // Create display value with \"Comparison\" prefix when hideCheckbox is true\n const displayValue =\n hideCheckbox && selectValue\n ? {\n ...selectValue,\n label: `Comparison: ${selectValue.label}`,\n }\n : selectValue;\n\n return (\n <ButtonGroup>\n {!hideCheckbox && (\n <ToolbarButton\n variant=\"canvas\"\n tooltip={t(\n 'grafana-scenes.components.scene-time-range-compare-renderer.button-tooltip',\n 'Enable time frame comparison'\n )}\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onClick();\n }}\n >\n <Checkbox label=\" \" value={enabled} onClick={onClick} />\n <Trans i18nKey=\"grafana-scenes.components.scene-time-range-compare-renderer.button-label\">Comparison</Trans>\n </ToolbarButton>\n )}\n\n {showSelect ? (\n <ButtonSelect\n variant=\"canvas\"\n value={displayValue}\n options={compareOptions}\n onChange={(v) => {\n model.onCompareWithChanged(v.value!);\n }}\n />\n ) : (\n <ToolbarButton className={styles.previewButton} disabled variant=\"canvas\" isOpen={false}>\n {previousValue.label}\n </ToolbarButton>\n )}\n </ButtonGroup>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n previewButton: css({\n '&:disabled': {\n border: `1px solid ${theme.colors.secondary.border}`,\n color: theme.colors.text.disabled,\n opacity: 1,\n },\n }),\n };\n}\n"],"names":["value"],"mappings":"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"}
@@ -7,15 +7,6 @@ function writeSceneLog(logger, message, ...rest) {
7
7
  console.log(`${logger}: `, message, ...rest);
8
8
  }
9
9
  }
10
- function writeSceneLogStyled(logger, message, style, ...rest) {
11
- let loggingEnabled = false;
12
- if (typeof window !== "undefined") {
13
- loggingEnabled = localStorage.getItem("grafana.debug.scenes") === "true";
14
- }
15
- if (loggingEnabled) {
16
- console.log(`%c${logger}: ${message}`, style, ...rest);
17
- }
18
- }
19
10
 
20
- export { writeSceneLog, writeSceneLogStyled };
11
+ export { writeSceneLog };
21
12
  //# sourceMappingURL=writeSceneLog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"writeSceneLog.js","sources":["../../../src/utils/writeSceneLog.ts"],"sourcesContent":["export function writeSceneLog(logger: string, message: string, ...rest: unknown[]) {\n let loggingEnabled = false;\n\n if (typeof window !== 'undefined') {\n loggingEnabled = localStorage.getItem('grafana.debug.scenes') === 'true';\n }\n\n if (loggingEnabled) {\n console.log(`${logger}: `, message, ...rest);\n }\n}\n\nexport function writeSceneLogStyled(logger: string, message: string, style: string, ...rest: unknown[]) {\n let loggingEnabled = false;\n\n if (typeof window !== 'undefined') {\n loggingEnabled = localStorage.getItem('grafana.debug.scenes') === 'true';\n }\n\n if (loggingEnabled) {\n console.log(`%c${logger}: ${message}`, style, ...rest);\n }\n}\n"],"names":[],"mappings":"AAAgB,SAAA,aAAA,CAAc,MAAgB,EAAA,OAAA,EAAA,GAAoB,IAAiB,EAAA;AACjF,EAAA,IAAI,cAAiB,GAAA,KAAA;AAErB,EAAI,IAAA,OAAO,WAAW,WAAa,EAAA;AACjC,IAAiB,cAAA,GAAA,YAAA,CAAa,OAAQ,CAAA,sBAAsB,CAAM,KAAA,MAAA;AAAA;AAGpE,EAAA,IAAI,cAAgB,EAAA;AAClB,IAAA,OAAA,CAAQ,IAAI,CAAG,EAAA,MAAM,CAAM,EAAA,CAAA,EAAA,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA;AAE/C;AAEO,SAAS,mBAAoB,CAAA,MAAA,EAAgB,OAAiB,EAAA,KAAA,EAAA,GAAkB,IAAiB,EAAA;AACtG,EAAA,IAAI,cAAiB,GAAA,KAAA;AAErB,EAAI,IAAA,OAAO,WAAW,WAAa,EAAA;AACjC,IAAiB,cAAA,GAAA,YAAA,CAAa,OAAQ,CAAA,sBAAsB,CAAM,KAAA,MAAA;AAAA;AAGpE,EAAA,IAAI,cAAgB,EAAA;AAClB,IAAQ,OAAA,CAAA,GAAA,CAAI,KAAK,MAAM,CAAA,EAAA,EAAK,OAAO,CAAI,CAAA,EAAA,KAAA,EAAO,GAAG,IAAI,CAAA;AAAA;AAEzD;;;;"}
1
+ {"version":3,"file":"writeSceneLog.js","sources":["../../../src/utils/writeSceneLog.ts"],"sourcesContent":["export function writeSceneLog(logger: string, message: string, ...rest: unknown[]) {\n let loggingEnabled = false;\n\n if (typeof window !== 'undefined') {\n loggingEnabled = localStorage.getItem('grafana.debug.scenes') === 'true';\n }\n\n if (loggingEnabled) {\n console.log(`${logger}: `, message, ...rest);\n }\n}\n"],"names":[],"mappings":"AAAgB,SAAA,aAAA,CAAc,MAAgB,EAAA,OAAA,EAAA,GAAoB,IAAiB,EAAA;AACjF,EAAA,IAAI,cAAiB,GAAA,KAAA;AAErB,EAAI,IAAA,OAAO,WAAW,WAAa,EAAA;AACjC,IAAiB,cAAA,GAAA,YAAA,CAAa,OAAQ,CAAA,sBAAsB,CAAM,KAAA,MAAA;AAAA;AAGpE,EAAA,IAAI,cAAgB,EAAA;AAClB,IAAA,OAAA,CAAQ,IAAI,CAAG,EAAA,MAAM,CAAM,EAAA,CAAA,EAAA,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA;AAE/C;;;;"}
package/dist/index.d.ts CHANGED
@@ -1308,13 +1308,6 @@ declare class UserActionEvent extends BusEventWithPayload<UserActionEventPayload
1308
1308
  */
1309
1309
  declare function lookupVariable(name: string, sceneObject: SceneObject): SceneVariable | null;
1310
1310
 
1311
- interface LongFrameEvent {
1312
- duration: number;
1313
- timestamp: number;
1314
- method: 'manual' | 'loaf';
1315
- }
1316
- type LongFrameCallback = (event: LongFrameEvent) => void;
1317
-
1318
1311
  interface QueryResultWithState {
1319
1312
  state: LoadingState;
1320
1313
  }
@@ -1325,9 +1318,6 @@ interface SceneQueryControllerEntry {
1325
1318
  cancel?: () => void;
1326
1319
  }
1327
1320
  type SceneQueryControllerEntryType = 'data' | 'annotations' | 'variable' | 'alerts' | 'plugin' | string;
1328
-
1329
-
1330
-
1331
1321
  interface SceneInteractionProfileEvent {
1332
1322
  origin: string;
1333
1323
  duration: number;
@@ -1338,8 +1328,6 @@ interface SceneInteractionProfileEvent {
1338
1328
  crumbs: string[];
1339
1329
  startTs: number;
1340
1330
  endTs: number;
1341
- longFramesCount: number;
1342
- longFramesTotalTime: number;
1343
1331
  }
1344
1332
  interface SceneQueryStateControllerState extends SceneObjectState {
1345
1333
  isRunning: boolean;
@@ -1535,23 +1523,6 @@ declare class PanelContextEventBus implements EventBus {
1535
1523
  newScopedBus(key: string, filter: EventFilterOptions): EventBus;
1536
1524
  }
1537
1525
 
1538
- /**
1539
- * SceneRenderProfiler tracks dashboard interaction performance including:
1540
- * - Total interaction duration
1541
- * - Network time
1542
- * - Long frame detection (50ms threshold) during interaction using LoAF API (default) or manual tracking (fallback)
1543
- * - Slow frame detection (30ms threshold) for tail recording after interaction
1544
- *
1545
- * Long frame detection during interaction:
1546
- * - 50ms threshold aligned with LoAF API default
1547
- * - LoAF API preferred (Chrome 123+) with manual fallback
1548
- * - Provides script attribution when using LoAF API
1549
- *
1550
- * Slow frame detection for tail recording:
1551
- * - 30ms threshold for post-interaction monitoring
1552
- * - Manual frame timing measurement
1553
- * - Captures rendering delays after user interaction completes
1554
- */
1555
1526
  declare class SceneRenderProfiler {
1556
1527
  #private;
1557
1528
  private queryController?;