Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions pages/CoreWebVitals/CLS.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,23 @@ This script displays the CLS value when the focus of the browser is switched to
#### Snippet

```js copy
let cumulativeLayoutShiftScore = 0;
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (!entry.hadRecentInput) {
cumulativeLayoutShiftScore += entry.value;
}
let cumulativeLayoutShiftScore = 0;
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (!entry.hadRecentInput) {
cumulativeLayoutShiftScore += entry.value;
}
});
}
});

observer.observe({ type: "layout-shift", buffered: true });
observer.observe({ type: "layout-shift", buffered: true });

document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
observer.takeRecords();
observer.disconnect();
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
observer.takeRecords();
observer.disconnect();

console.log(`CLS: ${cumulativeLayoutShiftScore}`);
}
});
console.log(`CLS: ${cumulativeLayoutShiftScore}`);
}
});
```


6 changes: 3 additions & 3 deletions pages/CoreWebVitals/LCP-Image-Entropy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Context: [Largest Contentful Paint change in Chrome 112 to ignore low-entropy images](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/speed/metrics_changelog/2023_04_lcp.md)

This snippet is based on and with the permission [Stoyan Stefanov](https://twitter.com/stoyanstefanov), read his post [here](https://www.phpied.com/quick-bpp-image-entropy-check/).
This snippet is based on and with the permission of [Stoyan Stefanov](https://twitter.com/stoyanstefanov), read his post [here](https://www.phpied.com/quick-bpp-image-entropy-check/).

With the script you can get a list of the BPP of all(1) images loaded on the site.

Expand All @@ -14,13 +14,13 @@ With the script you can get a list of the BPP of all(1) images loaded on the sit
console.table(
[...document.images]
.filter(
(img) => img.currentSrc != "" && !img.currentSrc.includes("data:image")
(img) => img.currentSrc != "" && !img.currentSrc.includes("data:image"),
)
.map((img) => [
img.currentSrc,
(performance.getEntriesByName(img.currentSrc)[0]?.encodedBodySize * 8) /
(img.width * img.height),
])
.filter((img) => img[1] !== 0)
.filter((img) => img[1] !== 0),
);
```
38 changes: 18 additions & 20 deletions pages/CoreWebVitals/LCP-Sub-Parts.mdx
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
### Largest Contentful Paint Sub-Parts (LCP)

This script it's part of the [Web Vitals Chrome Extension](https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma) and appear on the [Optimize Largest Contentful Paint](https://web.dev/i18n/en/optimize-lcp/) post.
This script is part of the [Web Vitals Chrome Extension](https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma) and appear on the [Optimize Largest Contentful Paint](https://web.dev/i18n/en/optimize-lcp/) post.


#### Snippet
#### Snippet

```js copy
const LCP_SUB_PARTS = [
'Time to first byte',
'Resource load delay',
'Resource load time',
'Element render delay',
"Time to first byte",
"Resource load delay",
"Resource load time",
"Element render delay",
];

new PerformanceObserver((list) => {
const lcpEntry = list.getEntries().at(-1);
const navEntry = performance.getEntriesByType('navigation')[0];
const navEntry = performance.getEntriesByType("navigation")[0];
const lcpResEntry = performance
.getEntriesByType('resource')
.getEntriesByType("resource")
.filter((e) => e.name === lcpEntry.url)[0];

const ttfb = navEntry.responseStart;
const lcpRequestStart = Math.max(
ttfb,
lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0
lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0,
);
const lcpResponseEnd = Math.max(
lcpRequestStart,
lcpResEntry ? lcpResEntry.responseEnd : 0
lcpResEntry ? lcpResEntry.responseEnd : 0,
);
const lcpRenderTime = Math.max(
lcpResponseEnd,
lcpEntry ? lcpEntry.startTime : 0
lcpEntry ? lcpEntry.startTime : 0,
);

LCP_SUB_PARTS.forEach((part) => performance.clearMeasures(part));
Expand All @@ -56,18 +56,16 @@ new PerformanceObserver((list) => {
];

// Log helpful debug information to the console.
console.log('LCP value: ', lcpRenderTime);
console.log('LCP element: ', lcpEntry.element, lcpEntry?.url);
console.log("LCP value: ", lcpRenderTime);
console.log("LCP element: ", lcpEntry.element, lcpEntry?.url);
console.table(
lcpSubPartMeasures.map((measure) => ({
'LCP sub-part': measure.name,
'Time (ms)': measure.duration,
'% of LCP': `${
"LCP sub-part": measure.name,
"Time (ms)": measure.duration,
"% of LCP": `${
Math.round((1000 * measure.duration) / lcpRenderTime) / 10
}%`,
}))
})),
);
}).observe({type: 'largest-contentful-paint', buffered: true});
}).observe({ type: "largest-contentful-paint", buffered: true });
```


8 changes: 4 additions & 4 deletions pages/CoreWebVitals/LCP.mdx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Largest Contentful Paint (LCP)

The next scripts show information about the [LCP](https://web.dev/lcp) metric.
The next scripts shows information about the [LCP](https://web.dev/lcp) metric.

> You can use it in the browser console or as snippet in the Chrome DevTools Source tab, take a look to the [Introduction](/introduction/) section.
> You can use it in the browser console or as a snippet in the Chrome DevTools Source tab, take a look at the [Introduction](/introduction/) section.

## Get the LCP element

List the Largest Contentful Paint in the console and add a green dotted line in the LCP element.
List the Largest Contentful Paint in the console and add a green dotted line around the LCP element.

#### Snippet

Expand All @@ -19,7 +19,7 @@ const po = new PerformanceObserver((list) => {
entries.forEach((item, i) => {
console.dir(item);
console.log(
`${i + 1} current LCP item : ${item.element}: ${item.startTime}`
`${i + 1} current LCP item : ${item.element}: ${item.startTime}`,
);
item.element ? (item.element.style = "border: 5px dotted lime;") : "";
});
Expand Down
79 changes: 48 additions & 31 deletions pages/Interaction/Interactions.mdx
Original file line number Diff line number Diff line change
@@ -1,75 +1,92 @@
# Interactions

This script it's part of the [Web Vitals Chrome Extension](https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma) and allows you to track all interactions as you click around the page to help improve INP.
This script is part of the [Web Vitals Chrome Extension](https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma) and allows you to track all interactions as you click around the page to help improve INP.


#### Snippet

```js copy
const valueToRating = (score) => score <= 200 ? 'good' : score <= 500 ? 'needs-improvement' : 'poor';
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 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
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)) {
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 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(
`Interaction tracking snippet %c${formattedValue} (${rating})`,
`color: ${RATING_COLORS[rating] || 'inherit'}`
`color: ${RATING_COLORS[rating] || "inherit"}`,
);
console.log('Interaction target:', entry.target);
console.log("Interaction target:", entry.target);

for (let entry of interaction) {
console.log(`Interaction event type: %c${entry.name}`, 'font-family: monospace');
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),
}]);
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',
type: "event",
durationThreshold: 0, // 16 minimum by spec
buffered: true
buffered: true,
});
```

3 changes: 1 addition & 2 deletions pages/Interaction/Layout-Shift-Loading-and-Interaction.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Layout Shift Loading and Interaction
# Layout Shift Loading and Interaction

Print all the CLS metrics during page load and when the user interacts with the page:

Expand All @@ -9,4 +9,3 @@ new PerformanceObserver((entryList) => {
console.log(entryList.getEntries());
}).observe({ type: "layout-shift", buffered: true });
```

Loading