Last active
June 2, 2023 12:17
-
-
Save tunetheweb/20ffc5719352dd86c215636729760c5c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Credit to Michal Mocny (https://twitter.com/mmocny) | |
// | |
// Copy and paste this into the console and click around to see all interactions, whether they would pass INP, | |
// and if you expand the entry you'll see the debug breakdown information. | |
// | |
// This is basically the same as the Core Web Vitals extension does: https://web.dev/debug-cwvs-with-web-vitals-extension/ | |
const valueToRating = (score) => score <= 200 ? 'good' : score <= 500 ? 'needs-improvement' : 'poor'; | |
const COLOR_GOOD = '#0CCE6A'; | |
const COLOR_NEEDS_IMPROVEMENT = '#FFA400'; | |
const COLOR_POOR = '#FF4E42'; | |
const RATING_COLORS = { | |
'good': COLOR_GOOD, | |
'needs-improvement': COLOR_NEEDS_IMPROVEMENT, | |
'poor': COLOR_POOR | |
}; | |
const observer = new PerformanceObserver((list) => { | |
const interactions = {}; | |
for (const entry of list.getEntries().filter((entry) => entry.interactionId)) { | |
interactions[entry.interactionId] = interactions[entry.interactionId] || []; | |
interactions[entry.interactionId].push(entry); | |
} | |
// Will report as a single interaction even if parts are in separate frames. | |
// Consider splitting by animation frame. | |
for (const interaction of Object.values(interactions)) { | |
const entry = interaction.reduce((prev, curr) => prev.duration >= curr.duration ? prev : curr); | |
const value = entry.duration; | |
const rating = valueToRating(value); | |
const formattedValue = `${value.toFixed(0)} ms`; | |
console.groupCollapsed( | |
`INP Snippet %c${formattedValue} (${rating})`, | |
`color: ${RATING_COLORS[rating] || 'inherit'}` | |
); | |
console.log('Interaction target:', entry.target); | |
for (let entry of interaction) { | |
console.log(`Interaction event type: %c${entry.name}`, 'font-family: monospace'); | |
// RenderTime is an estimate, because duration is rounded, and may get rounded down. | |
// In rare cases it can be less than processingEnd and that breaks performance.measure(). | |
// Lets make sure its at least 4ms in those cases so you can just barely see it. | |
const adjustedPresentationTime = Math.max(entry.processingEnd + 4, entry.startTime + entry.duration); | |
console.table([{ | |
subPartString: 'Input delay', | |
'Time (ms)': Math.round(entry.processingStart - entry.startTime, 0), | |
}, | |
{ | |
subPartString: 'Processing time', | |
'Time (ms)': Math.round(entry.processingEnd - entry.processingStart, 0), | |
}, | |
{ | |
subPartString: 'Presentation delay', | |
'Time (ms)': Math.round(adjustedPresentationTime - entry.processingEnd, 0), | |
}]); | |
} | |
console.groupEnd(); | |
} | |
}); | |
observer.observe({ | |
type: 'event', | |
durationThreshold: 0, // 16 minimum by spec | |
buffered: true | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment