-
Notifications
You must be signed in to change notification settings - Fork 4
Description
I have a very simple page where I provide an option to add an item via 2 buttons: button-1 and button-2, the onClick handlers for both buttons have a small difference, one has an empty while loop running for 3s while the other runs for 4s.
The code for the page is below for reference. Now when I click any of the buttons and see the console, where I am interested in the Long Animation Frames entry inside the logged object, the source function and the source url is different from the expected output. The page can be found here (deployed on vercel, the image below shows output on localhost): Deployed Page Link
Code:
"use client";
import { useState, useEffect, useRef } from "react";
import { onINP, onCLS } from "web-vitals/attribution";
import { FadeInAnimation } from "./animation.js";
interface Item {
id: number;
name: string;
category: string;
}
export default function INPPage() {
const [items, setItems] = useState<Item[]>([]);
const [show, setShow] = useState(false);
function Welcome() {
const ref = useRef(null);
useEffect(() => {
const animation = new FadeInAnimation(ref.current);
animation.start(1000);
return () => {
animation.stop();
};
}, []);
return (
<h1
ref={ref}
style={{
opacity: 0,
color: "white",
padding: 50,
textAlign: "center",
fontSize: 50,
backgroundImage:
"radial-gradient(circle, rgba(63,94,251,1) 0%, rgba(252,70,107,1) 100%)",
}}
>
Welcome
</h1>
);
}
useEffect(() => {
const REPORTING_THRESHOLD_MS = 150;
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log("LKJHGFDSDFGHJKL ", entry)
if (
entry.duration > REPORTING_THRESHOLD_MS &&
entry.firstUIEventTimestamp > 0
) {
console.log("Long task detected:", entry)
}
}
});
observer.observe({ type: "long-animation-frame", buffered: true });
console.log("Printing something");
onINP(console.log, { reportAllChanges: true });
}, []);
const handleAddItem = () => {
const newItem = { id: items.length + 1, name: "", category: "" };
const start = Date.now();
while (Date.now() - start < 3000) {}
setItems([...items, newItem]);
};
const handleAddItem4s = () => {
const newItem = { id: items.length + 1, name: "", category: "" };
const start = Date.now();
while (Date.now() - start < 4000) {}
setItems([...items, newItem]);
};
const handleInputChange = (id: number, field: string, value: string) => {
setItems(
items.map((item) => (item.id === id ? { ...item, [field]: value } : item))
);
};
return (
<div className="min-h-screen bg-gray-100 p-4">
<div className="container mx-auto p-4 bg-gray-800 text-white rounded shadow-lg"> {/* Updated background color and text color */}
<h1 className="text-2xl font-bold mb-4">INP Test Page with LoAF</h1>
<button onClick={() => setShow(!show)}>
{show ? "Remove" : "Show"}
</button>
<hr />
{show && <Welcome />}
<br />
<br />
<button
onClick={handleAddItem}
className="mb-4 px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-400"
>
Add Item (3s)
</button>
<button
onClick={handleAddItem4s}
className="mb-4 px-6 py-3 bg-green-500 text-white rounded-lg hover:bg-green-400"
>
Add Item (4s)
</button>
<div className="grid grid-cols-1 gap-4">
{items.map((item) => (
<div key={item.id} className="p-4 bg-gray-200 rounded-lg shadow-md">
<div className="mb-2">
<label className="block text-sm font-medium text-gray-700">
Name
</label>
<input
type="text"
value={item.name}
onChange={(e) =>
handleInputChange(item.id, "name", e.target.value)
}
className="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700">
Category
</label>
<input
type="text"
value={item.category}
onChange={(e) =>
handleInputChange(item.id, "category", e.target.value)
}
className="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
/>
</div>
</div>
))}
</div>
</div>
</div>
);
}Output Image:
Highlighted above is the sourceFunctionName and the sourceURL. In my application there is no such thing. I only clicked on the two buttons which you can see for which the function names which handle them are: handleAddItem and handleAddItem4s.
I went through the documentation for the same here: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceScriptTiming/sourceFunctionName as well, but it does not provide a great idea into the attribute (expected behaviour and the result), if the output can't be changed, is there a way to get the exact function which is taking a lot of time/blocking the main single thread ? Similarly for the sourceURL attribute as well. Since this is a relatively new addition, I could not find much resources apart from the original docs to look into it.
It would be great if this could be please looked into once and some details be provided about how to go about getting the correct source functions and in a broader sense action items to understand the metric in depth.
Thanks!
