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

Feature: Add LCP Element Attribution #1378

Open
simonhearne opened this issue Jun 19, 2023 · 2 comments
Open

Feature: Add LCP Element Attribution #1378

simonhearne opened this issue Jun 19, 2023 · 2 comments

Comments

@simonhearne
Copy link

The LargestContentfulPaint API exposes the element property for attribution of the element that triggered the LCP value.

This has value in front-end monitoring as it enables developers to determine which elements are responsible for high LCP values, e.g. large hero images, especially as LCP elements can vary by viewport size.

I have created a temporary solution below which captures element.tagName and element.src for the case of images and adds these as labels to the APM beacon. Ideally these would be first class properties on RUM transactions with LCP values.

// capture LCP attribution
var lcp = {};
const observer = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1]; // Use the latest LCP candidate
  console.log(lastEntry.element);
  lcp.elementType = lastEntry.element.tagName;
  lcp.elementURL = lastEntry.element.hasAttribute('src') ? lastEntry.element.src : '';
});
observer.observe({ type: "largest-contentful-paint", buffered: true });

//...

elasticApm.observe('transaction:end', tr =>  {
  if (typeof(lcp) !== 'undefined') {
    elasticApm.addLabels({'lcpElementType':lcp.elementType});
    elasticApm.addLabels({'lcpElementURL':lcp.elementURL});
  }
  //...
});
@1davidmichael
Copy link

Something like this would also be handy for INP. I'm doing something similar where I'm adding web-vitals with attribution to get the element and class name for the top scoring INP item.

Right now we have an easy way to see if we have bad scores with INP and LCP, but not determine what element is possibly causing it via RUM.

@1davidmichael
Copy link

I've been working on this for awhile and have come up with a solution where I'm using web-vitals with attribution to add labels on a custom transaction to associate the INP score with what caused it. I'm not sure if its useful but could be handy to implement natively here.

function logToAPM(...args) {
  const inpInfo = args; // Spread syntax to convert arguments to array
  const transaction = elasticApm.startTransaction(pageName(), "inp");
  console.debug(args);

  inpInfo.forEach((inp) => {
    inp.entries.forEach((entry) => {
      const tagName = entry.target?.tagName?.toLowerCase() ?? "N/A";
      const className = entry.target?.className ?? "N/A";

      const labels = {
        inpDuration: inp?.value,
        inpTag: tagName,
        inpClass: className,
        inpRating: inp?.rating,
        inpName: entry?.name,
        templateType: pageName(),
        inpInteractionTarget: inp?.attribution?.interactionTarget,
      };

      const span = transaction.startSpan(entry.name, "inp", {
        startTime: entry.startTime,
      });
      span.addLabels(labels);
      span.end({ endTime: entry.startTime + entry.duration });
    });
  });

  transaction.end();
  console.debug(transaction);
}

webVitals.onINP(logToAPM)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants