Claude Skills Guide

Chrome Extension Page Speed Insights: A Developer’s Guide

Page performance remains a critical factor for user experience and search engine rankings. For developers building Chrome extensions focused on performance analysis, understanding the Page Speed Insights API and related browser APIs opens up powerful possibilities. This guide walks you through building extensions that analyze and report page speed metrics.

Understanding the Page Speed Insights API

Google’s Page Speed Insights API provides detailed performance analysis based on Lighthouse audits. The API returns metrics including Largest Contentful Paint (LCP), First Input Delay (FID), Cumulative Layout Shift (CLS), and Speed Index. These metrics align with Core Web Vitals, making them essential for modern web development.

To use the API, send a request to:

https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=TARGET_URL&key=YOUR_API_KEY

The response includes performance scores, numeric metrics, and actionable recommendations. For a Chrome extension, you’ll want to wrap this API call and present results in a user-friendly interface.

Building Your First Page Speed Extension

Create a Chrome extension that fetches and displays page speed data. Start with the manifest file:

{
  "manifest_version": 3,
  "name": "Page Speed Insights",
  "version": "1.0",
  "permissions": ["activeTab", "storage"],
  "action": {
    "default_popup": "popup.html"
  },
  "host_permissions": ["https://www.googleapis.com/"]
}

The popup HTML provides the interface:

<!DOCTYPE html>
<html>
<head>
  <style>
    body { width: 400px; padding: 16px; font-family: system-ui; }
    .metric { margin: 12px 0; }
    .score { font-weight: bold; font-size: 24px; }
    .good { color: #0cce6b; }
    .needs-improvement { color: #ffa400; }
    .poor { color: #ff4e42; }
  </style>
</head>
<body>
  <h2>Page Speed Analysis</h2>
  <div id="results">Loading...</div>
  <script src="popup.js"></script>
</body>
</html>

The popup JavaScript handles the API call:

const API_KEY = 'YOUR_PAGE_SPEED_API_KEY';

document.addEventListener('DOMContentLoaded', async () => {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  const url = encodeURIComponent(tab.url);
  
  const response = await fetch(
    `https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=${url}&key=${API_KEY}`
  );
  const data = await response.json();
  
  displayResults(data.lighthouseResult.audits);
});

function displayResults(audits) {
  const metrics = ['largest-contentful-paint', 'first-input-delay', 'cumulative-layout-shift', 'speed-index'];
  let html = '';
  
  metrics.forEach(metric => {
    const audit = audits[metric];
    const score = audit.score;
    const value = audit.displayValue;
    const cls = score >= 0.9 ? 'good' : score >= 0.5 ? 'needs-improvement' : 'poor';
    
    html += `<div class="metric">
      <div>${audit.title}</div>
      <div class="score ${cls}">${value}</div>
    </div>`;
  });
  
  document.getElementById('results').innerHTML = html;
}

Using Chrome DevTools Protocol for Advanced Analysis

For deeper analysis, the Chrome DevTools Protocol (CDP) provides real-time metrics directly from the browser. This approach works without external API calls and gives you access to performance traces.

async function getPerformanceMetrics(tabId) {
  const client = await chrome.debugger.attach({ tabId }, '1.3');
  
  const result = await chrome.debugger.sendCommand(
    { tabId },
    'Performance.getMetrics'
  );
  
  const metrics = {};
  result.metrics.forEach(m => {
    metrics[m.name] = m.value;
  });
  
  return {
    jsHeapUsed: metrics.JSHeapUsedSize,
    nodes: metrics.Nodes,
    layoutCount: metrics.LayoutCount,
    styleRecalcCount: metrics.RecalcStyleCount
  };
}

This code connects to the active tab’s debugging interface and retrieves memory and rendering metrics. You can detect memory leaks, excessive reflows, and other performance issues in real-time.

Measuring Core Web Vitals Programmatically

Core Web Vitals are essential for understanding user-perceived performance. You can measure these directly in your extension using the web vitals library or the Performance API.

function measureLCP(callback) {
  if (!('PerformanceObserver' in window)) {
    callback({ value: -1, rating: 'not supported' });
    return;
  }
  
  let lcpValue = 0;
  const observer = new PerformanceObserver((entryList) => {
    const entries = entryList.getEntries();
    const lastEntry = entries[entries.length - 1];
    lcpValue = lastEntry.renderTime || lastEntry.loadTime;
  });
  
  observer.observe({ entryTypes: ['largest-contentful-paint'] });
  
  // Report final value after page load
  window.addEventListener('load', () => {
    setTimeout(() => {
      callback({ value: lcpValue, rating: lcpValue < 2500 ? 'good' : 'needs-improvement' });
      observer.disconnect();
    }, 2000);
  });
}

function measureCLS(callback) {
  let clsValue = 0;
  const observer = new PerformanceObserver((entryList) => {
    for (const entry of entryList.getEntries()) {
      if (!entry.hadRecentInput) {
        clsValue += entry.value;
      }
    }
  });
  
  observer.observe({ entryTypes: ['layout-shift'] });
  
  window.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'hidden') {
      callback({ value: clsValue, rating: clsValue < 0.1 ? 'good' : 'needs-improvement' });
    }
  });
}

These functions integrate into your extension’s content script or popup to give users immediate feedback on Core Web Vitals.

Storing Historical Data

Track performance over time using Chrome’s storage API. This helps identify trends and correlate performance changes with code deployments.

async function saveMetric(url, metricName, value) {
  const key = `metrics_${metricName}`;
  const result = await chrome.storage.local.get(key);
  const history = result[key] || [];
  
  history.push({
    url,
    value,
    timestamp: Date.now()
  });
  
  // Keep last 100 entries per metric
  const trimmed = history.slice(-100);
  await chrome.storage.local.set({ [key]: trimmed });
}

async function getMetricHistory(metricName) {
  const key = `metrics_${metricName}`;
  const result = await chrome.storage.local.get(key);
  return result[key] || [];
}

Best Practices for Production Extensions

When deploying your page speed extension, consider these practical tips:

Rate limiting and caching: The Page Speed Insights API has usage limits. Implement caching to avoid redundant calls for recently analyzed URLs. Store results in chrome.storage with a timestamp, and serve cached data if requested within the last five minutes.

Error handling: Network requests fail. Always implement fallback logic:

try {
  const response = await fetch(apiUrl);
  if (!response.ok) throw new Error(`API error: ${response.status}`);
  return await response.json();
} catch (error) {
  // Show user-friendly error or fall back to local metrics
  console.error('Page Speed API error:', error);
  return getLocalMetrics();
}

User privacy: Only store metrics users explicitly save. Never send data to third-party servers without clear consent. Keep all analysis local when possible.

Conclusion

Building a Chrome extension for page speed insights combines web performance APIs, Chrome’s extension framework, and user interface design. The techniques covered here—using the Page Speed Insights API, measuring Core Web Vitals, accessing Chrome DevTools Protocol, and storing historical data—provide a solid foundation for creating powerful performance analysis tools.

With this knowledge, you can create extensions that help developers identify bottlenecks, track improvements over time, and deliver faster web experiences. The APIs and methods shown here represent the current standard for browser-based performance analysis.

Built by theluckystrike — More at zovo.one