Skip to content

Commit

Permalink
[Perfomance] Add is_initial_load meta (#206645)
Browse files Browse the repository at this point in the history
closes elastic/observability-dev#4185 

## Summary

This PR adds the `is_initial_load` parameter to the meta field to
distinguish whether the `onPageReady` trigger occurs during the initial
load or a page refresh.

Refactoring: 
- Removed the `target` field. as `context.pageName` now provides the
necessary information
- Refactor APM instrumentation to simplify it

Fixes: 
- elastic/observability-dev#3464  


### ⚠️  Instrumentation 

The plugins need to call the following function: 

``` onPageRefreshStart()```


This method adds a performance marker `start::pageRefresh` to indicate when a page refresh begins. This marker is used along with an end marker `end::pageReady` to determine the total refresh duration.


 
https://github.com/user-attachments/assets/62587d18-b33e-437b-9774-d8e196dbf764

https://github.com/user-attachments/assets/e9c9a761-57bc-4743-9cc7-ea7634696ee3



### How to test
- Checkout the PR
- make sure you run `yarn kbn bootstrap`
- go to any page that has onPageReady function instrumented (ex services)  


### TODO
- Once approved, update docs

---------

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
kpatticha and elasticmachine authored Feb 25, 2025
1 parent 471c413 commit 9a1d70d
Show file tree
Hide file tree
Showing 23 changed files with 405 additions and 265 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ describe('trackPerformanceMeasureEntries', () => {
anyKey: 'anyKey',
anyValue: 'anyValue',
},
meta: {
isInitialLoad: true,
queryRangeSecs: 86400,
queryOffsetSecs: 0,
},
},
},
]);
Expand All @@ -124,7 +129,7 @@ describe('trackPerformanceMeasureEntries', () => {
duration: 1000,
eventName: 'kibana:plugin_render_time',
key1: 'key1',
meta: { target: '/' },
meta: { is_initial_load: true, query_range_secs: 86400, query_offset_secs: 0 },
value1: 'value1',
});
});
Expand Down Expand Up @@ -152,7 +157,7 @@ describe('trackPerformanceMeasureEntries', () => {
expect(analyticsClientMock.reportEvent).toHaveBeenCalledWith('performance_metric', {
duration: 1000,
eventName: 'kibana:plugin_render_time',
meta: { target: '/', query_range_secs: 86400, query_offset_secs: 0 },
meta: { query_range_secs: 86400, query_offset_secs: 0 },
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ export function trackPerformanceMeasureEntries(analytics: AnalyticsClient, isDev
duration,
...customMetrics,
meta: {
target,
query_range_secs: meta?.queryRangeSecs,
query_offset_secs: meta?.queryOffsetSecs,
is_initial_load: meta?.isInitialLoad,
},
});
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,25 @@ import {
getOffsetFromNowInSeconds,
getTimeDifferenceInSeconds,
} from '@kbn/timerange';
import { perfomanceMarkers } from '../../performance_markers';
import { EventData } from '../performance_context';
import { perfomanceMarkers } from '../../performance_markers';

interface PerformanceMeta {
queryRangeSecs: number;
queryOffsetSecs: number;
isInitialLoad?: boolean;
}

export function measureInteraction() {
export function measureInteraction(pathname: string) {
performance.mark(perfomanceMarkers.startPageChange);
const trackedRoutes: string[] = [];

return {
/**
* Marks the end of the page ready state and measures the performance between the start of the page change and the end of the page ready state.
* @param pathname - The pathname of the page.
* @param customMetrics - Custom metrics to be included in the performance measure.
*/
pageReady(pathname: string, eventData?: EventData) {
pageReady(eventData?: EventData) {
let performanceMeta: PerformanceMeta | undefined;
performance.mark(perfomanceMarkers.endPageReady);

Expand All @@ -49,19 +50,48 @@ export function measureInteraction() {
};
}

if (!trackedRoutes.includes(pathname)) {
performance.measure(pathname, {
if (
performance.getEntriesByName(perfomanceMarkers.startPageChange).length > 0 &&
performance.getEntriesByName(perfomanceMarkers.endPageReady).length > 0
) {
performance.measure(`[ttfmp:initial] - ${pathname}`, {
detail: {
eventName: 'kibana:plugin_render_time',
type: 'kibana:performance',
customMetrics: eventData?.customMetrics,
meta: performanceMeta,
meta: { ...performanceMeta, isInitialLoad: true },
},
start: perfomanceMarkers.startPageChange,
end: perfomanceMarkers.endPageReady,
});
trackedRoutes.push(pathname);

// Clean up the marks once the measure is done
performance.clearMarks(perfomanceMarkers.startPageChange);
performance.clearMarks(perfomanceMarkers.endPageReady);
}

if (
performance.getEntriesByName(perfomanceMarkers.startPageRefresh).length > 0 &&
performance.getEntriesByName(perfomanceMarkers.endPageReady).length > 0
) {
performance.measure(`[ttfmp:refresh] - ${pathname}`, {
detail: {
eventName: 'kibana:plugin_render_time',
type: 'kibana:performance',
customMetrics: eventData?.customMetrics,
meta: { ...performanceMeta, isInitialLoad: false },
},
start: perfomanceMarkers.startPageRefresh,
end: perfomanceMarkers.endPageReady,
});

// // Clean up the marks once the measure is done
performance.clearMarks(perfomanceMarkers.startPageRefresh);
performance.clearMarks(perfomanceMarkers.endPageReady);
}
},
pageRefreshStart() {
performance.mark(perfomanceMarkers.startPageRefresh);
},
};
}
Loading

0 comments on commit 9a1d70d

Please sign in to comment.