Page Speed Optimization: The Complete Guide to Faster Websites

11 sections 6 min read

Page speed optimization is the work of making pages load, become usable, and stay stable faster for real visitors. It covers the server, the files that block rendering, images, code, caching, and delivery. Core Web Vitals are the measures Google uses for page experience; this guide covers the work that moves them and the diagnostic metrics that tell you where the time is going.

The Metrics That Explain Speed

The three Core Web Vitals are Largest Contentful Paint (loading), Interaction to Next Paint (responsiveness), and Cumulative Layout Shift (visual stability). Google’s Web Vitals overview gives their thresholds. Three more metrics help explain why those numbers look the way they do:

Metric What it measures Published guidance
First Contentful Paint When any content first appears 1.8 seconds or less
Time to First Byte How long the server takes to start responding 0.8 seconds or less, as a rough guide
Total Blocking Time How long the main thread is blocked during load (lab only) 0 to 200 ms is green in Lighthouse on mobile

Sources for the rows: web.dev on First Contentful Paint and Time to First Byte, and Lighthouse documentation on Total Blocking Time.

Field data from real visitors, shown in Search Console and PageSpeed Insights, decides whether a page passes Core Web Vitals. Lab tools such as Lighthouse run controlled tests that help find causes. A strong lab score with weak field data can mean real visitors use slower devices or networks than the test assumed.

Server Response

Nothing renders until the first byte of HTML arrives, so a slow server delays everything after it. The common causes on dynamic sites are slow database queries, work repeated on every request that could be cached, and hosting without enough resources for the traffic. Object and opcode caches, full-page caching where content does not change per visitor, and properly sized hosting address those. Distance between server and visitor adds latency that application work cannot remove, which is the problem a CDN’s edge network solves.

Render-Blocking Files

The browser cannot paint until it has processed the CSS and synchronous JavaScript in the critical path.

  • Inline the CSS needed for the first screen and load the rest asynchronously.
  • Load non-critical JavaScript with defer or async, choosing between them by dependency. Web.dev’s guide to resource loading explains that async scripts “may execute out-of-order, while defer scripts are executed in the order in which they appear in the markup,” after the document is parsed. A script that depends on another script or on the finished page belongs with defer; an independent one, such as an analytics tag, can use async.
  • Use font-display: swap so text appears in a fallback font while a web font downloads, and preload the font files the first screen needs:
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
<style>
  @font-face {
    font-family: 'Main';
    src: url('/fonts/main.woff2') format('woff2');
    font-display: swap;
  }
</style>

Images

Images can be a large share of a page’s bytes; HTTP Archive’s page weight report tracks image bytes over time for desktop and mobile. Measure your own pages rather than relying on an average.

  • Serve modern formats such as WebP and AVIF, and measure the savings per image.
  • Serve each device an image sized for its screen with srcset and sizes, and give every image width and height so the browser reserves space. The sizes value below assumes a layout where the image fills a 400-pixel column on screens up to 600 pixels wide and an 800-pixel column above that; write it from your own CSS, and write alt text that says what the image shows:
<img
  src="product-800.webp"
  srcset="product-400.webp 400w, product-800.webp 800w, product-1600.webp 1600w"
  sizes="(max-width: 600px) 400px, 800px"
  alt="Red road running shoe, top view"
  width="800" height="600">
  • Lazy-load images below the first screen with loading="lazy", but not the main image. Google’s LCP guide warns: “Never lazy-load your LCP image, as that will always lead to unnecessary resource load delay, and will have a negative impact on LCP.”
  • Image CDNs can automate format conversion, resizing, and compression at delivery.

Code

  • Minify CSS and JavaScript in the build.
  • Split large JavaScript bundles so each page loads only the code it uses, and remove unused code during the build.
  • Enable Brotli or Gzip compression on the server for HTML, CSS, and JavaScript.
  • Audit third-party scripts. Remove those that do not earn their place, load the rest asynchronously, and use a click-to-load placeholder for heavy embeds such as video players and chat widgets.

Caching and Delivery

  • Browser caching headers (Cache-Control) let returning visitors reuse files.
  • Versioned file names, such as style.a3f9c1.css, let you cache files for a long time and still serve the new version immediately after a deploy.
  • A service worker can cache an application shell for fast repeat visits.
  • A CDN serves cached files from locations near each visitor. Uncacheable requests still go to the origin, so origin location still matters for an audience concentrated in one region.

One Workable Order

Measure first, and start with the largest delay the measurement shows. Where nothing points elsewhere, this order follows how a page loads:

  1. Fix server response time, since front-end work cannot make up for a slow first byte.
  2. Remove render-blocking files.
  3. Optimize the element that sets LCP on each template, such as a hero image or a large text block.
  4. Fix layout shift sources: unsized images, late-loading banners and ads, font swaps without matched fallbacks.
  5. Work on long JavaScript tasks and interaction delays, which need profiling to diagnose.

Matching Symptoms to Causes

Symptom Likely cause First fix to try
Slow LCP, fast TTFB Render-blocking files or a heavy LCP image Inline critical CSS, preload the LCP image, defer scripts
Slow LCP, slow TTFB Server response Query optimization, caching, hosting
High CLS Unsized images, injected content, font swaps Set dimensions, reserve space, use matched fallback fonts
Poor INP Long main-thread tasks Break up tasks, defer scripts, move work off the main thread
Good lab score, poor field data Test conditions faster than real visitors Test with throttling; check field data by device

Mobile

Test on mid-range phones and throttled connections, not only on a fast desktop. CPU speed varies widely across phones, and a page that loads well on office Wi-Fi can stall on an unstable mobile connection.

Keeping It Fast

Record a baseline before changing anything. Collect real-user data, run lab tests on every deploy, and set performance budgets, such as a limit on JavaScript size or a target LCP, that the build checks. New features, content, and third-party scripts erode speed gradually when nobody is watching.

Questions About Page Speed

Does page speed affect rankings?
Google uses Core Web Vitals in its ranking systems, and its page experience documentation says the other page experience aspects do not directly lift rankings. Speed also matters directly to visitors, whatever its weight in ranking.

Should I aim for a PageSpeed Insights score of 100?
The score is a lab summary. The field data behind Core Web Vitals is what reflects your visitors, so aim to pass those at the 75th percentile and use the lab score to find causes.