chromedevtools--chrome-devtools-mcp
2cd9b95346
This is a draft for new skill to debug and optimize LCP scores, going hand in hand with https://github.com/ChromeDevTools/chrome-devtools-mcp/pull/831. Base for this skill is key authoritative learning material from web.dev, about debugging and optimizing LCP, mainly: - http://web.dev/articles/lcp - http://web.dev/articles/optimize-lcp - https://web.dev/articles/top-cwv I gave the content of those articles together with the [tool reference](https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/docs/tool-reference.md), the README and the chrome-devtools core skill to both Claude Opus 4.6 and Gemini 3 Pro and their respective skill creator skills. The final skill in this PR is a merge of multiple runs with both models. The snippets to run with `evaluate_script` is something only Opus came up with, but I think it's quite nice, though our own `performance_*` tools might give the same insight but likely with more overhead (meaning tokens).
2.4 KiB
2.4 KiB
LCP Debugging Snippets
Use these JavaScript snippets with the evaluate_script tool to extract deep insights from the page.
1. Identify LCP Element
Use this snippet to identify the LCP element and get raw timing data from the Performance API.
async () => {
return await new Promise(resolve => {
new PerformanceObserver(list => {
const entries = list.getEntries();
const last = entries[entries.length - 1];
resolve({
element: last.element?.tagName,
id: last.element?.id,
className: last.element?.className,
url: last.url,
startTime: last.startTime,
renderTime: last.renderTime,
loadTime: last.loadTime,
size: last.size,
});
}).observe({type: 'largest-contentful-paint', buffered: true});
});
};
2. Audit Common Issues
Use this snippet to check for common DOM-based LCP issues (lazy loading, priority).
() => {
const issues = [];
// Check for lazy-loaded images in viewport
document.querySelectorAll('img[loading="lazy"]').forEach(img => {
const rect = img.getBoundingClientRect();
if (rect.top < window.innerHeight) {
issues.push({
issue: 'lazy-loaded image in viewport',
element: img.outerHTML.substring(0, 200),
fix: 'Remove loading="lazy" from this image — it is in the initial viewport and may be the LCP element',
});
}
});
// Check for LCP-candidate images missing fetchpriority
document.querySelectorAll('img:not([fetchpriority])').forEach(img => {
const rect = img.getBoundingClientRect();
if (rect.top < window.innerHeight && rect.width * rect.height > 50000) {
issues.push({
issue: 'large viewport image without fetchpriority',
element: img.outerHTML.substring(0, 200),
fix: 'Add fetchpriority="high" to this image — it is large and visible in the initial viewport',
});
}
});
// Check for render-blocking scripts in head
document
.querySelectorAll(
'head script:not([async]):not([defer]):not([type="module"])',
)
.forEach(script => {
if (script.src) {
issues.push({
issue: 'render-blocking script in head',
element: script.outerHTML.substring(0, 200),
fix: 'Add async or defer attribute, or move to end of body',
});
}
});
return {issueCount: issues.length, issues};
};