Skip to content

Latest commit

 

History

History
76 lines (44 loc) · 8.92 KB

0003-browser-js-built-in-metrics.md

File metadata and controls

76 lines (44 loc) · 8.92 KB
  • Start Date: 2022-08-18
  • RFC Type: feature
  • RFC PR: #3
  • RFC Status: approved
  • RFC Driver: Abhijeet Prasad

Expanding Built-In Performance Metrics for Browser JavaScript.

Summary

This RFC details expanding list of built-in performance metrics for the browser JavaScript SDK, with additional data the Browser SDK captures. It propose adding a metric that is already captured by the SDK: connection.rtt, and a brand new metric that is not yet captured, inp.

Note: References to performance metrics (external name) are equivalent to measurements (internal name) for the purpose of this document.

Background

The Sentry product now supports the ability to set Performance Metrics in the product, via attaching numeric tags to transaction data. Internally, we refer to these numeric tags as measurements. Some of these performance metrics are considered "built-in", and are automatically sent from certain SDKs. These built-in performance metrics are defined in an explicit allowlist in Sentry's Relay config, and are defined in Relay themselves as well.

The Browser JavaScript SDKs currently has seven built-in performance metrics, fp, fcp, lcp, fid, cls, ttfb, and ttfb.requesttime. In addition to built-in performance metrics, the product supports sending arbitrary custom performance metrics on transactions. For example in JavaScript:

const transaction = Sentry.getCurrentHub().getScope().getTransaction();

// Record amount of times localStorage was read
transaction.setMeasurement('localStorageRead', 4);

In the product, we display the built-in performance metrics and custom performance metrics in different sections of the event details. In addition, transactions have a limit of 5 custom performance metrics that they can send.

Proposals

Existing Data

Aside from the seven built-in performance metrics the JavaScript SDKs set, the JavaScript SDK also sets connection.rtt and connection.downlink as performance metrics. Since these are not in the built-in allow list in Relay/Sentry, they are considered custom performance metrics, and take away from the custom performance metric quota that exists on transactions.

connection.rtt is the the estimated effective round-trip time of the current connection, rounded to the nearest multiple of 25 milliseconds. connection.downlink is the effective bandwidth estimate in megabits per second, rounded to the nearest multiple of 25 kilobits per seconds. These were originally added to the SDK Oct 2020 to help grab info about network connectivity information.

Here, we propose that we should remove the reporting of connection.downlink and move connection.rtt to be a built-in performance metrics. connection.rtt will help users understand the network conditons of their transactions at a high level, and help them see how using things like PoP servers or more aggressive caching maybe help their pageload times. At a high level, connection.rtt should help the developer understand general network conditions across their production performance data.

We need to make a decision about connection.downlink and connection.rtt, as they are taking away from user's custom performance metrics quota.

New Data

A new metric we would like to introduce is inp. inp, or Interaction to Next Paint is the newest chrome web vital. We've already had some user interest in adopting this, as we already support the other web vitals (lcp, fcp, etc.). inp also opens the door for us to introduce user interaction instrumentation, like creating transactions to measure the performance of user clicks or inputs.

To instrument inp in our SDK, we require the usage of the web-vitals v3 library, but we can go ahead and make it a built-in performance metrics beforehand.

Rollout

As we are only adding two built-in performance metrics, we will not have to do a phased rollout plan. Instead the rollout is as follows:

  1. Add connection.rtt as a built-in metric to Relay/Sentry.

  2. Update the JS SDK to stop sending connection.downlink, as we are only going to send connection.rtt as a performance metric.

  3. Add inp as a built-in metric to Relay/Sentry.

  4. Update the JS SDK to web vitals v3.

  5. Add inp performance metric to all JS Browser SDK transactions.

Appendix

Removed Proposals

In the initial version of the proposal, a new built-in performance metric long_task.count was proposed. This was dropped because of the high burden of introducing too many built-in performance metrics. Below we've included the rationale for including long_task.count in the first place.

Long Tasks are JavaScript tasks that take 50ms or longer to execute. They are considered problematic because JavaScript is single threaded, so blocking the main thread is a big performance hit. In the SDK, we track individual long task occurences as spans and record them onto transactions.

In Sentry, we've been recording longTaskCount on transactions as a Custom Performance Metric for the Sentry frontend. So far, tracking the longTaskCount has been valuable as it allows us at a high level to see the most problematic transactions when looking at CPU usage. Since we already record long task spans in the SDK, it should be fairly easy to generate the count as a measurement, and promote into a built-in measurement. Here we would use long_task.count as the measurement name instead of longTaskCount that we used for internal testing.

In the second version of the proposal, it was proposed that device.memory and hardware.concurrency would be inlcuded as new built-in performance metrics. This was removed because of the low value of these metrics and the fact that they are limiting in the data they provide. For device.memory, it seems that WebKit won't ever support this. In addition, it's imprecise OOB for fingerprinting reasons. hardware.concurrency is valuable since it can help users decide on usage of APIs like Web Workers, but perhaps it's better suited in processor_count under Device Context. Below we've included the rationale for including device.memory and hardware.concurrency in the first place.

In the same PR that added connection.rtt and connection.downlink, we also added support for grabbing deviceMemory and hardwareConcurrency. Currently these are set as tags on the transaction. This should become performance metrics, as SDKs should not be settings tags like this one events, and there is value in seeing these numeric values on transactions. Here we would also rename deviceMemory -> device.memory and hardwareConcurrency -> hardware.concurrency.

Another additional option is to move all browser Navigator related fields into a brand new SDK context - that is avaliable to all events, not just performance ones.