GoogleChrome / web-vitals

Essential metrics for a healthy site.
https://web.dev/vitals
Apache License 2.0
7.62k stars 418 forks source link

Add more LoAF diagnostics to the INP attribution object #559

Open rviscomi opened 3 weeks ago

rviscomi commented 3 weeks ago

Currently, web-vitals provides the raw LoAF entries in the INP attribution object, which consumers of the library need to parse themselves to extract useful diagnostic info about the interaction. To make the attribution object more readily consumable, web-vitals should pre-process a core set of useful LoAF-based diagnostics.

After experimenting with different INP diagnostics, this is the subset that I've found to be most useful, including some existing metrics:

Diagnostics in bold are the ones I think every site owner should be looking at, with the rest considered nice to have. All of the unchecked items represent the ones I'm proposing we add first-class support for in web-vitals. These could be added directly to the attribution object, or contained within some nested object like loafAttribution.

web-vitals should only report the durations that occur during the interaction. A script could already be running at the moment a user interacts, but the only relevant time for attribution purposes is the time since the interaction started. Similarly, any scripts that have already finished executing before the interaction should be completely ignored from all INP diagnostics, even if they happen to occur within the same LoAF entry as the interaction.

The attribution object might look something like this:

inp.attribution = {
  loafAttribution: {
    totalLoafEntries: 1,
    totalLoafScriptEntries: 2,
    totalStyleAndLayoutDuration: 30,
    totalForcedStyleAndLayoutDuration: 50,
    totalDurationsPerPhase: {
      inputDelay: {
        'classic-script': 100
      },
      processingDuration: {
        'event-listener': 200
      }
    },
    slowestScript: {
      phase: 'processingDuration',
      duration: 200,
      compileDuration: 10,
      executionDuration: 190,
      forcedStyleAndLayoutDuration: 50,
      pauseDuration: 0,
      invokerType: 'event-listener',
      invoker: 'BUTTON.onclick',
      sourceURL: 'https://example.com/script.js',
      sourceFunctionName: null,
      sourceCharPosition: -1,
      entry: [PerformanceScriptTiming object]
    }
  }
  ...
}