GoogleChrome / GoogleChrome/web-vitals
Target in FID and INP is null
- Dominant language
- JavaScript
- Stars
- 8.6k
- Forks
- 530
- Avg merge
- 3h 4m
- Merged PRs (30d)
- 3
Description
Hi guys,
Im using your nice script to measuer web vitals on our website. To make optimization easier, we are also persisting the target-elemtent. It works fine with CLS and LCP but in FID and INP I get "null" for the target Element as you can see in this screenshot:

This is how I use it:
```
import {onCLS, onFID, onLCP, onINP, onFCP, onTTFB} from "https://unpkg.com/web-vitals@3/dist/web-vitals.attribution.js?module";
function getIdOrNodeNamePlusClassList(node) {
return (node && node.nodeType !== 9) ? (node.id ?
"#" + node.id :
node.nodeName.toLowerCase() +
((node.className && node.className.length) ?
"." + Array.from(node.classList.values()).join(".") :
"")) : "";
}
function getLargestLayoutShiftEntry(entries) {
return entries.reduce((a, b) => a && a.value > b.value ? a : b);
}
function getLargestLayoutShiftSource(sources) {
return sources.reduce((a, b) => {
return a.node && a.previousRect.width * a.previousRect.height >
b.previousRect.width * b.previousRect.height ? a : b;
});
}
function getCausingElementIdentifier(name, entries = []) {
// In some cases there won't be any entries (e.g. if CLS is 0,
// or for LCP after a bfcache restore), so we have to check first.
if (entries.length && name !== "FCP" && name !== "TTFB") {
if (name === "LCP") {
const lastEntry = entries[entries.length - 1];
return getIdOrNodeNamePlusClassList(lastEntry.element);
} else if (name === "FID" || name === "INP") {
const firstEntry = entries[0];
return getIdOrNodeNamePlusClassList(firstEntry.target);
} else if (name === "CLS") {
const largestEntry = getLargestLayoutShiftEntry(entries);
if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
const largestSource = getLargestLayoutShiftSource(largestEntry.sources);
if (largestSource) {
return getIdOrNodeNamePlusClassList(largestSource.node);
}
}
}
}
return "";
}
function sendRUMData({name, value, attribution, entries}) {
if (name === "FID" || name === "INP") {
console.log("--- " + name + "(" + value +") ---");
console.log("- Entries -");
console.log(entries);
console.log("- Attribution -");
console.log(attribution);
console.log("- Causing -");
console.log(getCausingElementIdentifier(name, entries));
}
}
onCLS(sendRUMData);
onFCP(sendRUMData);
onFID(sendRUMData);
onINP(sendRUMData);
onLCP(sendRUMData);
onTTFB(sendRUMData);
```
Do you know why? Am I doing something wrong?
Contributor guide
Research direction
Start at the attribution.js entry point used by onFID and onINP, then inspect the callback's entries and attribution values for target data. Compare the observed FID and INP payloads with the CLS and LCP payloads; done means explaining whether null is expected and identifying any required usage change.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- performance
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100