BytePane

Web Performance Optimization Checklist for 2026

Performance16 min read

Why Performance Matters More Than Ever in 2026

Google's Core Web Vitals have been a ranking factor since 2021, and the thresholds have only gotten stricter. In 2026, Interaction to Next Paint (INP) has fully replaced First Input Delay (FID) as the responsiveness metric, and Google has raised the bar for what constitutes a "good" user experience. Sites that load slowly lose users, revenue, and search rankings.

Research from Google shows that as page load time increases from 1 second to 3 seconds, the probability of bounce increases by 32%. From 1 to 5 seconds, it increases by 90%. Every 100ms of latency costs Amazon approximately 1% in revenue. Performance is not an optimization -- it is a feature.

This checklist provides 50 actionable items organized by category. Work through them in order of impact, measure before and after, and keep iterating. Use tools like Google PageSpeed Insights, WebPageTest, and Chrome DevTools to validate your improvements.

Core Web Vitals Targets for 2026

MetricGoodNeeds ImprovementPoor
LCP (Largest Contentful Paint)≤ 2.5s2.5s - 4.0s> 4.0s
INP (Interaction to Next Paint)≤ 200ms200ms - 500ms> 500ms
CLS (Cumulative Layout Shift)≤ 0.10.1 - 0.25> 0.25

These metrics are measured at the 75th percentile of page loads. That means 75% of your real users must experience values below the "good" threshold for Google to consider your site passing.

Images and Media (Items 1-10)

Images are typically the largest assets on a web page and the primary cause of slow LCP scores. Optimizing images is often the highest-impact change you can make.

  1. Use modern formats -- Serve WebP or AVIF instead of PNG/JPEG. AVIF offers 50% smaller files than JPEG at equivalent quality. Use the <picture> element with fallbacks.
  2. Set explicit width and height -- Always include width and height attributes on images to prevent CLS.
  3. Lazy load below-the-fold images -- Use loading="lazy" for images not visible on initial viewport. Never lazy load the LCP image.
  4. Preload the LCP image -- Add <link rel="preload" as="image"> in the document head for the hero image.
  5. Use responsive images -- Serve appropriately sized images with srcset and sizes attributes.
  6. Compress images -- Use tools like Sharp, Squoosh, or ImageOptim. Target 80-85% quality for photos.
  7. Use CSS for decorative elements -- Gradients, shadows, and simple shapes should be CSS, not images.
  8. Inline critical SVGs -- Small SVG icons should be inlined to avoid extra HTTP requests.
  9. Use a CDN for images -- Image CDNs like Cloudflare Images, Imgix, or Cloudinary handle format conversion and resizing automatically.
  10. Implement fetchpriority -- Set fetchpriority="high" on the LCP image and fetchpriority="low" on below-the-fold images.

JavaScript Optimization (Items 11-20)

JavaScript is the most expensive resource on the web because it must be downloaded, parsed, compiled, and executed. Reducing JavaScript payload is critical for both LCP and INP.

  1. Code split by route -- Use dynamic imports to load only the JavaScript needed for the current page. Most bundlers (Webpack, Vite, Rollup) support this natively.
  2. Tree shake unused code -- Ensure your bundler eliminates dead code. Use ES modules (import/export) instead of CommonJS for tree-shaking support.
  3. Defer non-critical scripts -- Use defer or async attributes. Third-party analytics and tracking scripts should never block rendering.
  4. Minify and compress -- Use Terser for minification and Brotli compression (20-25% smaller than gzip) for transfer.
  5. Audit npm dependencies -- Run npx bundlephobia or use Import Cost in VS Code. Replace heavy libraries with lighter alternatives (date-fns instead of Moment.js).
  6. Use web workers for heavy computation -- Move CPU-intensive work off the main thread to keep the UI responsive and improve INP.
  7. Break up long tasks -- Tasks longer than 50ms block the main thread. Use scheduler.yield() or requestIdleCallback to break them up.
  8. Avoid layout thrashing -- Batch DOM reads and writes. Reading a layout property after a write forces a synchronous layout recalculation.
  9. Use requestAnimationFrame for visual updates -- Schedule DOM changes in rAF to align with the browser's render cycle.
  10. Remove unused polyfills -- In 2026, most browsers support ES2022+. Drop polyfills for features like Promise, fetch, and Array.flat().

To analyze your JavaScript bundles, use our JavaScript Beautifier to deobfuscate minified code and understand what is being shipped to the browser.

CSS Optimization (Items 21-28)

  1. Inline critical CSS -- Extract the CSS needed for above-the-fold content and inline it in the <head>. Load the rest asynchronously.
  2. Remove unused CSS -- Use PurgeCSS or the Coverage tab in Chrome DevTools to identify and remove dead CSS rules.
  3. Minify CSS -- Use cssnano, Lightning CSS, or esbuild for CSS minification.
  4. Use CSS containment -- Apply contain: layout paint to isolate component rendering and reduce browser work.
  5. Prefer CSS over JavaScript for animations -- CSS animations and transitions run on the compositor thread and do not block the main thread.
  6. Use content-visibility: auto -- Skip rendering for off-screen content. This can dramatically reduce initial rendering time for long pages.
  7. Avoid @import in CSS -- CSS @import creates sequential network requests. Use build tools to concatenate CSS files instead.
  8. Use modern CSS features -- Features like :has(), container queries, and @layer reduce the need for JavaScript-driven layouts. See our CSS :has() Selector Guide.

Format and validate your CSS with our CSS Formatter to ensure consistent, clean stylesheets before optimization.

Network and Caching (Items 29-38)

  1. Enable Brotli compression -- Brotli provides 15-25% better compression than gzip for text assets. Most CDNs and web servers support it.
  2. Set long cache headers for static assets -- Use Cache-Control: max-age=31536000, immutable for hashed filenames.
  3. Use a CDN -- Serve static assets from edge locations close to your users. Cloudflare, Fastly, and CloudFront all offer free or low-cost tiers.
  4. Preconnect to required origins -- Add <link rel="preconnect"> for third-party domains you load resources from (fonts, analytics, APIs).
  5. Use HTTP/2 or HTTP/3 -- HTTP/2 multiplexing eliminates head-of-line blocking. HTTP/3 (QUIC) further improves performance on lossy connections.
  6. Implement service workers -- Cache critical assets for instant repeat visits and offline support. Use Workbox for a simpler API.
  7. Prefetch next-page resources -- Use <link rel="prefetch"> for resources the user is likely to need next (e.g., the next page in a multi-step flow).
  8. Use 103 Early Hints -- Supported by major CDNs in 2026, Early Hints let the browser start loading critical resources before the server finishes generating the response.
  9. Minimize redirects -- Each redirect adds a full round-trip. Eliminate unnecessary chains. Check your redirect configuration against our HTTP Status Codes Guide.
  10. Use stale-while-revalidate -- This cache strategy serves stale content immediately while fetching a fresh version in the background, combining speed with freshness.

Fonts (Items 39-43)

  1. Use font-display: swap -- Show fallback text immediately while the custom font loads. This prevents invisible text (FOIT).
  2. Preload critical fonts -- Add <link rel="preload" as="font" crossorigin> for the one or two fonts used above the fold.
  3. Subset fonts -- Remove unused glyphs. A full Google Fonts file can be 100KB+, but subsetting to Latin characters often reduces it to 15-20KB.
  4. Self-host fonts -- Hosting fonts on your own domain eliminates the DNS lookup and connection to Google Fonts or other third-party servers.
  5. Use variable fonts -- A single variable font file replaces multiple weight/style files, reducing total font payload by 30-70%.

Server and Infrastructure (Items 44-50)

  1. Optimize Time to First Byte (TTFB) -- Keep TTFB under 200ms. Use server-side caching, database query optimization, and edge computing. A slow TTFB makes it impossible to achieve good LCP.
  2. Use server-side rendering or static generation -- Pre-render HTML on the server so the browser receives ready-to-display content instead of an empty shell.
  3. Implement edge-side rendering -- Use edge functions (Cloudflare Workers, Vercel Edge) to generate personalized content at the CDN edge.
  4. Set up a performance budget -- Define maximum sizes for JavaScript (< 200KB gzipped), CSS (< 50KB), and total page weight (< 1MB). Fail CI/CD builds that exceed the budget.
  5. Monitor real user metrics (RUM) -- Use the Web Vitals library or a RUM tool to collect Core Web Vitals data from actual users, not just synthetic tests.
  6. Automate Lighthouse in CI -- Run Lighthouse in your CI/CD pipeline and block deployments that regress performance scores. See our CI/CD Pipeline Guide for integration examples.
  7. Database query optimization -- Add indexes, use query caching, and implement connection pooling. Slow database queries are the most common cause of high TTFB in dynamic applications.

Measurement and Testing

Performance optimization without measurement is guesswork. Use both lab tools (synthetic tests with controlled conditions) and field data (real user measurements) to validate your improvements.

// Measure Core Web Vitals in JavaScript
import { onLCP, onINP, onCLS } from 'web-vitals';

onLCP((metric) => {
  console.log('LCP:', metric.value, 'ms');
  // Send to your analytics endpoint
  sendToAnalytics({ name: 'LCP', value: metric.value });
});

onINP((metric) => {
  console.log('INP:', metric.value, 'ms');
  sendToAnalytics({ name: 'INP', value: metric.value });
});

onCLS((metric) => {
  console.log('CLS:', metric.value);
  sendToAnalytics({ name: 'CLS', value: metric.value });
});

// Performance Observer for custom metrics
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log(`${entry.name}: ${entry.duration}ms`);
  }
});
observer.observe({ type: 'measure', buffered: true });

// Mark and measure custom operations
performance.mark('api-start');
await fetch('/api/data');
performance.mark('api-end');
performance.measure('API Call', 'api-start', 'api-end');
ToolTypeBest For
PageSpeed InsightsLab + FieldQuick Core Web Vitals check with real user data
WebPageTestLabDetailed waterfall analysis, filmstrip comparison
Chrome DevToolsLabPerformance profiling, network throttling, Coverage
CrUX DashboardFieldHistorical field data trends from Chrome users
web-vitals libraryFieldCustom RUM implementation in your code

Quick Wins: The Five Highest-Impact Changes

If you can only do five things, do these. They typically account for 80% of the performance improvement on most websites.

  1. Convert images to WebP/AVIF -- Often reduces image payload by 40-60% with no visible quality loss.
  2. Enable Brotli compression -- A server configuration change that shrinks all text assets by 15-25% compared to gzip.
  3. Code split your JavaScript -- Load only the code needed for the current page. This is the single biggest JavaScript optimization.
  4. Preload the LCP resource -- Tell the browser about your hero image or heading font early, saving hundreds of milliseconds.
  5. Set width/height on images and embeds -- Prevents layout shift, often fixing CLS scores instantly with zero effort.

Optimize Your CSS and JavaScript

Clean, well-formatted code is easier to optimize. Use our free CSS Formatter and JavaScript Beautifier to organize your code before running performance audits.

Related Articles