@@ -11,6 +11,7 @@ import { getFID } from './web-vitals/getFID';
1111import { getLCP } from './web-vitals/getLCP' ;
1212import { getTTFB } from './web-vitals/getTTFB' ;
1313import { getFirstHidden } from './web-vitals/lib/getFirstHidden' ;
14+ import { NavigatorDeviceMemory , NavigatorNetworkInformation } from './web-vitals/types' ;
1415
1516const global = getGlobalObject < Window > ( ) ;
1617
@@ -129,6 +130,8 @@ export class MetricsInstrumentation {
129130
130131 this . _performanceCursor = Math . max ( performance . getEntries ( ) . length - 1 , 0 ) ;
131132
133+ this . _trackNavigator ( transaction ) ;
134+
132135 // Measurements are only available for pageload transactions
133136 if ( transaction . op === 'pageload' ) {
134137 transaction . setMeasurements ( this . _measurements ) ;
@@ -149,6 +152,46 @@ export class MetricsInstrumentation {
149152 } ) ;
150153 }
151154
155+ /**
156+ * Capture the information of the user agent.
157+ */
158+ private _trackNavigator ( transaction : Transaction ) : void {
159+ const navigator = global . navigator as null | ( Navigator & NavigatorNetworkInformation & NavigatorDeviceMemory ) ;
160+
161+ if ( ! navigator ) {
162+ return ;
163+ }
164+
165+ // track network connectivity
166+
167+ const connection = navigator . connection ;
168+ if ( connection ) {
169+ if ( connection . effectiveType ) {
170+ transaction . setTag ( 'effectiveConnectionType' , connection . effectiveType ) ;
171+ }
172+
173+ if ( connection . type ) {
174+ transaction . setTag ( 'connectionType' , connection . type ) ;
175+ }
176+
177+ if ( isMeasurementValue ( connection . rtt ) ) {
178+ this . _measurements [ 'connection.rtt' ] = { value : connection . rtt as number } ;
179+ }
180+
181+ if ( isMeasurementValue ( connection . downlink ) ) {
182+ this . _measurements [ 'connection.downlink' ] = { value : connection . downlink as number } ;
183+ }
184+ }
185+
186+ if ( isMeasurementValue ( navigator . deviceMemory ) ) {
187+ transaction . setTag ( 'deviceMemory' , String ( navigator . deviceMemory ) ) ;
188+ }
189+
190+ if ( isMeasurementValue ( navigator . hardwareConcurrency ) ) {
191+ transaction . setTag ( 'hardwareConcurrency' , String ( navigator . hardwareConcurrency ) ) ;
192+ }
193+ }
194+
152195 /** Starts tracking the Largest Contentful Paint on the current page. */
153196 private _trackLCP ( ) : void {
154197 getLCP ( metric => {
@@ -332,3 +375,10 @@ export function _startChild(transaction: Transaction, { startTimestamp, ...ctx }
332375 ...ctx ,
333376 } ) ;
334377}
378+
379+ /**
380+ * Checks if a given value is a valid measurement value.
381+ */
382+ function isMeasurementValue ( value : any ) : boolean {
383+ return typeof value === 'number' && isFinite ( value ) ;
384+ }
0 commit comments