Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add INP breakdown timings and LoAF attribution #442

Merged
merged 25 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5e61149
Remove missed polyfill code
philipwalton Mar 10, 2024
84abacf
Remove unused rollup plugin
philipwalton Mar 11, 2024
98d9090
Add frame-based INP and LoAF attribution
philipwalton Mar 9, 2024
c68c21b
Add additional code comments
philipwalton Mar 11, 2024
078c577
Merge branch 'v4' into loaf-inp
tunetheweb Mar 11, 2024
5d6a09b
Update src/types.ts
philipwalton Mar 11, 2024
be0b1d3
Update src/onINP.ts
philipwalton Mar 11, 2024
8f3b241
Address review feedback
philipwalton Mar 18, 2024
a41d463
Update README to match latest JSDocs
philipwalton Mar 18, 2024
32a47e1
Apply suggestions from code review
philipwalton Mar 19, 2024
4847ecd
Address review feedback
philipwalton Mar 19, 2024
06abad2
Add fallback for requestIdleCallback
philipwalton Mar 19, 2024
9034cd4
Add missing null check
philipwalton Mar 20, 2024
82a9b6e
Rename processingTime to processingDuration
philipwalton Mar 20, 2024
9271d29
Update tests to reduce flakiness
philipwalton Mar 22, 2024
012d5fa
Address review feedback
philipwalton Mar 22, 2024
8fd1ebb
Update type definitions and descriptions
philipwalton Mar 26, 2024
3d3709a
Update src/onINP.ts
philipwalton Mar 26, 2024
7a5515d
Revert interactionType to be pointer or keyboard
philipwalton Mar 27, 2024
ecf6960
Increase the past renderTimes frame length
philipwalton Mar 29, 2024
b59a791
Format code
philipwalton Mar 29, 2024
fa100e7
Update README.md
philipwalton Mar 29, 2024
dd644da
Update README
philipwalton Mar 29, 2024
c258ca4
Add test for LoAF entries
philipwalton Mar 29, 2024
157d1a8
Fix failing test
philipwalton Mar 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"files": ["test/e2e/*.js"],
"globals": {
"$": false,
"browser": false
"browser": false,
"__toSafeObject": false
},
"extends": ["eslint:recommended"],
"rules": {
Expand Down Expand Up @@ -63,6 +64,7 @@
"node/no-missing-require": "off",
"node/shebang": "off",
"no-dupe-class-members": "off",
"prefer-spread": "off",
"space-before-function-paren": [
"error",
{
Expand Down
98 changes: 77 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

## Overview

The `web-vitals` library is a tiny (~1.5K, brotli'd), modular library for measuring all the [Web Vitals](https://web.dev/articles/vitals) metrics on real users, in a way that accurately matches how they're measured by Chrome and reported to other Google tools (e.g. [Chrome User Experience Report](https://developers.google.com/web/tools/chrome-user-experience-report), [Page Speed Insights](https://developers.google.com/speed/pagespeed/insights/), [Search Console's Speed Report](https://webmasters.googleblog.com/2019/11/search-console-speed-report.html)).
The `web-vitals` library is a tiny (~2K, brotli'd), modular library for measuring all the [Web Vitals](https://web.dev/articles/vitals) metrics on real users, in a way that accurately matches how they're measured by Chrome and reported to other Google tools (e.g. [Chrome User Experience Report](https://developers.google.com/web/tools/chrome-user-experience-report), [Page Speed Insights](https://developers.google.com/speed/pagespeed/insights/), [Search Console's Speed Report](https://webmasters.googleblog.com/2019/11/search-console-speed-report.html)).

The library supports all of the [Core Web Vitals](https://web.dev/articles/vitals#core_web_vitals) as well as a number of other metrics that are useful in diagnosing [real-user](https://web.dev/articles/user-centric-performance-metrics) performance issues.

Expand Down Expand Up @@ -442,14 +442,14 @@ The following table lists all the builds distributed with the `web-vitals` packa
<td><code>web-vitals.umd.cjs</code></td>
<td><code>pkg.main</code></td>
<td>
A UMD version of the <code>web-vitals.js</code> bundle (exposed on the <code>window.webVitals.*</code> namespace).
A UMD version of the <code>web-vitals.js</code> bundle (exposed on the <code>self.webVitals.*</code> namespace).
philipwalton marked this conversation as resolved.
Show resolved Hide resolved
</td>
</tr>
<tr>
<td><code>web-vitals.iife.js</code></td>
<td>--</td>
<td>
An IIFE version of the <code>web-vitals.js</code> bundle (exposed on the <code>window.webVitals.*</code> namespace).
An IIFE version of the <code>web-vitals.js</code> bundle (exposed on the <code>self.webVitals.*</code> namespace).
</td>
</tr>
<tr>
Expand All @@ -463,15 +463,15 @@ The following table lists all the builds distributed with the `web-vitals` packa
<td><code>web-vitals.attribution.umd.cjs</code></td>
<td>--</td>
<td>
A UMD version of the <code>web-vitals.attribution.js</code> build (exposed on the <code>window.webVitals.*</code> namespace).
A UMD version of the <code>web-vitals.attribution.js</code> build (exposed on the <code>self.webVitals.*</code> namespace).
</td>
</tr>
</tr>
<tr>
<td><code>web-vitals.attribution.iife.js</code></td>
<td>--</td>
<td>
An IIFE version of the <code>web-vitals.attribution.js</code> build (exposed on the <code>window.webVitals.*</code> namespace).
An IIFE version of the <code>web-vitals.attribution.js</code> build (exposed on the <code>self.webVitals.*</code> namespace).
</td>
</tr>
</table>
Expand Down Expand Up @@ -877,31 +877,87 @@ interface FIDAttribution {
```ts
interface INPAttribution {
/**
* A selector identifying the element that the user interacted with for
* the event corresponding to INP. This element will be the `target` of the
* `event` dispatched.
* A selector identifying the element that the user first interacted with
philipwalton marked this conversation as resolved.
Show resolved Hide resolved
* as part of the frame where the INP candidate interaction occurred.
philipwalton marked this conversation as resolved.
Show resolved Hide resolved
* If `interactionTarget` is an empty string, that generally means the
* element was removed from the DOM as part of the interaction.
philipwalton marked this conversation as resolved.
Show resolved Hide resolved
philipwalton marked this conversation as resolved.
Show resolved Hide resolved
*/
eventTarget?: string;
interactionTarget: string;
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved

/**
* The time when the user interacted for the event corresponding to INP.
* This time will match the `timeStamp` value of the `event` dispatched.
* The time when the user first interacted during the frame where the INP
* candidate interaction occurred (if more than one interaction occurred
* within the frame, only the first time is reported).
*/
eventTime?: number;
interactionTime: DOMHighResTimeStamp;

/**
* The `type` of the `event` dispatched corresponding to INP.
* The best-guess timestamp of the next paint after the interaction.
* In general, this timestamp is the same as the `startTime + duration` of
* the event timing entry. However, since `duration` values are rounded to
* the nearest 8ms, it can sometimes appear that the paint occurred before
* processing ended (which cannot happen). This value clamps the paint time
* so it's always after `processingEnd` from the Event Timing API and
* `renderStart` from the Long Animation Frame API (where available).
* It also averages the duration values for all entries in the same
* animation frame, which should be closer to the "real" value.
*/
eventType?: string;
nextPaintTime: DOMHighResTimeStamp;

/**
* The `PerformanceEventTiming` entry corresponding to INP.
* The type of interaction, which corresponds to the event type of the first
* entry with an `interactionId` set, within the same animation frame as
* the interaction.
*/
eventEntry?: PerformanceEventTiming;
interactionType: 'pointerdown' | 'pointerup' | 'keydown' | 'keyup' | 'click';

/**
* The loading state of the document at the time when the even corresponding
* to INP occurred (see `LoadState` for details). If the interaction occurred
* while the document was loading and executing script (e.g. usually in the
* `dom-interactive` phase) it can result in long delays.
* An array of Event Timing entries that were processed within the same
* animation frame as the INP candidate interaction.
*/
loadState?: LoadState;
processedEventEntries: PerformanceEventTiming[];

/**
* If the browser supports the Long Animation Frame API, this array will
* include any `long-animation-frame` entries that intersect with the INP
* candidate interaction's `startTime` and the `processingEnd` time of the
* last event processed within that animation frame. If the browser does not
* support the Long Animation Frame API or no `long-animation-frame` entries
* are detect, this array will be empty.
*/
longAnimationFrameEntries: PerformanceLongAnimationFrameTiming[];

/**
* The time from when the user interacted with the page until when the
* browser was first able to start processing event listeners for that
* interaction. This time captures the delay before event processing can
* begin due to the main thread being busy with other work.
*/
inputDelay: number;

/**
* The time from when the first event listener started running in response to
* the user interaction until when all event listener processing has finished.
*/
processingDuration: number;

/**
* The time from when the browser finished processing all event listeners for
* the user interaction until the next frame is presented on the screen and
* visible to the user. This time includes work on the main thread (such as
* `requestAnimationFrame()` callbacks, `ResizeObserver` and
* `IntersectionObserver` callbacks, and style/layout calculation) as well
* as off-main-thread work (such as compositor, GPU, and raster work).
*/
presentationDelay: number;

/**
* The loading state of the document at the time when the interaction
* corresponding to INP occurred (see `LoadState` for details). If the
* interaction occurred while the document was loading and executing script
* (e.g. usually in the `dom-interactive` phase) it can result in long delays.
*/
loadState: LoadState;
}
```

Expand Down