Skip to content

Commit

Permalink
add method to measure Interaction to Next Paint (INP)
Browse files Browse the repository at this point in the history
`web-vitals` CHANGELOG for v3:

- [BREAKING] Report TTFB after a bfcache restore
- [BREAKING] Only include last LCP entry in metric entries
- Add support for the new INP metric
- Rename getXXX() functions to onXXX()
- Add a navigationType property to the Metric object

See https://github.com/GoogleChrome/web-vitals/blob/next/CHANGELOG.md
  • Loading branch information
Keen Yee Liau committed Jun 7, 2022
1 parent 3026fa5 commit bd0b4d3
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 24 deletions.
28 changes: 15 additions & 13 deletions packages/next/client/performance-relayer.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/* global location */
import {
getCLS,
getFCP,
getFID,
getLCP,
getTTFB,
onCLS,
onFCP,
onFID,
onINP,
onLCP,
onTTFB,
Metric,
ReportHandler,
ReportCallback,
} from 'next/dist/compiled/web-vitals'

const initialHref = location.href
let isRegistered = false
let userReportHandler: ReportHandler | undefined
let userReportHandler: ReportCallback | undefined

function onReport(metric: Metric): void {
if (userReportHandler) {
Expand Down Expand Up @@ -71,7 +72,7 @@ function onReport(metric: Metric): void {
}
}

export default (onPerfEntry?: ReportHandler): void => {
export default (onPerfEntry?: ReportCallback): void => {
// Update function if it changes:
userReportHandler = onPerfEntry

Expand All @@ -81,9 +82,10 @@ export default (onPerfEntry?: ReportHandler): void => {
}
isRegistered = true

getCLS(onReport)
getFID(onReport)
getFCP(onReport)
getLCP(onReport)
getTTFB(onReport)
onCLS(onReport)
onFID(onReport)
onFCP(onReport)
onLCP(onReport)
onTTFB(onReport)
onINP(onReport)
}
2 changes: 1 addition & 1 deletion packages/next/compiled/web-vitals/web-vitals.umd.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
"uuid": "8.3.2",
"vm-browserify": "1.1.2",
"watchpack": "2.4.0",
"web-vitals": "2.1.0",
"web-vitals": "3.0.0-beta.2",
"webpack-sources1": "npm:webpack-sources@1.4.3",
"webpack-sources3": "npm:webpack-sources@3.2.3",
"webpack4": "npm:webpack@4.44.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/next/shared/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export type NextWebVitalsMetric = {
} & (
| {
label: 'web-vital'
name: 'FCP' | 'LCP' | 'CLS' | 'FID' | 'TTFB'
name: 'FCP' | 'LCP' | 'CLS' | 'FID' | 'TTFB' | 'INP'
}
| {
label: 'custom'
Expand Down
27 changes: 19 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions test/integration/relay-analytics/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,21 @@ if (typeof navigator !== 'undefined') {
}
}

function toggleText(e) {
const startTime = performance.now()
while (performance.now() < startTime + 100) {
// busy waiting
}
e.target.textContent = e.target.textContent === 'Click' ? 'Press' : 'Click'
}

export default () => {
// Below comment will be used for replacing exported report method with hook based one.
return (
<div>
<h1>Foo!</h1>
<h2>bar!</h2>
<button onClick={toggleText}>Click</button>
</div>
)
}
14 changes: 14 additions & 0 deletions test/integration/relay-analytics/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,18 @@ function runTest() {
expect(stdout).toMatch('Next.js Analytics')
await browser.close()
})

it('reports INP metric', async () => {
const browser = await webdriver(appPort, '/')
await browser.elementByCss('button').click()
await browser.waitForCondition(
'document.querySelector("button").textContent === "Press"'
)
// INP metric is only reported on pagehide or visibilitychange event, so refresh the page
await browser.refresh()
const INP = parseInt(await browser.eval('localStorage.getItem("INP")'), 10)
// We introduced a delay of 100ms, so INP duration should be >= 100
expect(INP).toBeGreaterThanOrEqual(100)
await browser.close()
})
}

0 comments on commit bd0b4d3

Please sign in to comment.