Website Speed Optimization: How to Speed Up a Site

18 min read

Share
Speed gauge near its maximum, with image icons shrinking as they move toward it

Website speed optimization means sending visitors fewer bytes, sending the important ones first, and serving them from somewhere close and cached.

To increase the speed of your website pages and reduce load time, most sites get the biggest wins from the same short list:

  • resized and compressed images;
  • lighter video;
  • less render-blocking CSS and JavaScript;
  • text compression;
  • browser caching and a CDN;
  • a fast server response.

This guide goes through each one in the order you should tackle them to improve website performance, for WordPress sites and custom-coded sites alike.

How to increase the speed of website pages: quick checklist

If you only have an hour, work through this list from the top:

  1. Test the page in PageSpeed Insights and note which element is the Largest Contentful Paint (LCP).
  2. Resize and compress images to reduce their file size, and convert them to WebP or AVIF.
  3. Make sure the hero image is not lazy-loaded, and lazy-load everything below the fold.
  4. Replace animated GIFs and autoplaying background videos with small, muted MP4/WebM files, or remove them.
  5. Turn on Brotli or gzip compression and long cache lifetimes for static files.
  6. Defer non-essential JavaScript and remove scripts you no longer use.
  7. Put static files behind a CDN and check that they are actually being cached.
  8. On WordPress, add a page cache and remove plugins you don't need.

The sections below explain how to do each step and how to check it worked.

Check your website and page speed and performance

Run a page speed test in PageSpeed Insights first, then use Chrome DevTools or WebPageTest to see which files are slow.

Test your most important pages one by one (home page, top articles, product pages), because each page has its own speed and performance problems. Get this baseline before changing anything, otherwise you can't tell which change helped.

Three free tools cover most needs:

  • PageSpeed Insights shows two kinds of data. Field data comes from real Chrome users over the last 28 days (only for pages with enough traffic). Lab data is a single Lighthouse test run on Google's servers. Field data is what Google uses for Core Web Vitals; lab data is what you use to debug.
  • Chrome DevTools (Network and Performance panels) shows every request, its size, and what blocked the first paint.
  • WebPageTest gives a request-by-request waterfall from different locations and connection speeds.

What is a good Core Web Vitals score?

Google's Core Web Vitals are three metrics. web.dev publishes these thresholds, measured at the 75th percentile of page visits:

MetricWhat it measuresGoodPoor
LCP (Largest Contentful Paint)When the main content appears2.5 s or lessover 4 s
INP (Interaction to Next Paint)How quickly the page reacts to taps, clicks and keys200 ms or lessover 500 ms
CLS (Cumulative Layout Shift)How much the layout jumps while loading0.1 or lessover 0.25

Values in between are rated "needs improvement". INP replaced First Input Delay (FID) as a Core Web Vital in March 2024.

Why is my mobile speed score lower than desktop?

The mobile test simulates a mid-range phone on a slower mobile connection, so heavy JavaScript and large images hurt far more there. That is also closer to what many real visitors experience, so the mobile result is usually the one to fix first.

How to optimize images for a website

Images are usually the heaviest part of a page and often the LCP element, so this is where most sites gain the most speed. To optimize images for a website:

  1. Resize them to the size they are displayed at.
  2. Compress them to reduce image file size.
  3. Convert them to WebP or AVIF.
  4. Set their width and height.
  5. Lazy-load the ones below the fold.

Done well, this often cuts image size by half or more without a visible loss in quality.

What size should images be for a website?

Upload images at roughly the size they are shown, not at camera resolution. Resizing is the simplest way to reduce image file size: a 4000-pixel photo shown in an 800-pixel column wastes most of its bytes.

A good rule is about twice the displayed width for sharp screens. A photo shown 800 pixels wide needs about 1600 pixels, not 4000.

If you have a folder of product photos or blog images, a batch tool saves time. The Bulk Image Resizer resizes and compresses many JPG, PNG and WebP files at once in your browser.

Which image format is best for websites?

For most photos and screenshots, WebP or AVIF. They give the same visual quality in fewer bytes than JPEG or PNG.

FormatBest forSize compared with older formats
WebPPhotos, screenshots, images with transparencyLossless WebP is 26% smaller than PNG; lossy WebP is 25–34% smaller than JPEG (Google's WebP documentation)
AVIFPhotos where every kilobyte countsOften smaller than WebP, but slower to encode
SVGLogos, icons, simple illustrationsUsually the smallest option for flat graphics
PNG / JPEGFallback onlyLargest of the four for the same quality

Both WebP and AVIF are supported in current browsers. WebP is the safer default because almost every tool and CMS handles it; AVIF is worth using where your tools support it.

  • Photos and screenshots that are currently PNG are often the biggest win, because PNG is lossless and large. Convert them with the PNG to WebP converter, which keeps transparency.
  • For existing JPEG photos, the JPG to WebP converter shows the file size before and after so you can pick a quality level.
  • iPhone photos in HEIC can go straight to AVIF with the HEIC to AVIF converter.

How much can you compress images without losing quality?

For photos, a quality setting around 75–85 is a sensible starting point. It usually reduces the file size a lot with no difference most people can see.

To find the right setting for your images:

  1. Export at 85 and check the result at 100% zoom.
  2. Lower the quality step by step until you can see a difference.
  3. Go back up one step and use that setting.

The JPG and PNG to WebP converters above show the file size before and after, so you can compare as you go.

How do you stop images from shifting the layout?

Always give images a width and height (or a CSS aspect-ratio). The browser then reserves the space before the file arrives, so text doesn't jump down when the image loads.

Missing image dimensions are one of the most common causes of a poor CLS score.

Should you lazy-load every image?

No. Add loading="lazy" to images further down the page so they only load when the visitor scrolls near them. web.dev's guidance is to use it only for images outside the initial viewport.

The LCP image (usually the hero or the first large image) should load normally. You can also give it fetchpriority="high" so the browser fetches it before less important files.

How do you serve smaller images on mobile?

With srcset and sizes, a phone downloads a 600-pixel image while a large desktop screen gets the 1600-pixel version. WordPress generates these automatically for images added through the media library; on custom sites you either generate the sizes at build time or use an image CDN.

Does removing EXIF data make images smaller?

Slightly. Camera photos carry EXIF data: camera model, date, sometimes GPS location. Removing it usually saves a few kilobytes, more when the file has an embedded thumbnail.

The bigger benefit is privacy: you don't publish your location by accident. The Remove EXIF Data tool does this without re-compressing JPG and PNG files.

How to reduce video size and load time

The short answer: compress your videos, and don't make visitors download video they didn't ask for.

  • Replace animated GIFs with video. GIF is an inefficient format for animation. In web.dev's example, a 3.7 MB GIF became a 551 KB MP4 and a 341 KB WebM. Use a <video> element with autoplay, loop, muted and playsinline to get the same looping effect.
  • Think twice about hero background videos. A full-screen autoplaying video often costs more than everything else on the page combined. If you keep one, compress it hard, keep it short, and show a lightweight poster image first.
  • Don't preload what may never play. For videos the visitor has to click, use preload="none" (or metadata) and a poster image so nothing heavy downloads until they press play.
  • Use a facade for YouTube and Vimeo embeds. A standard YouTube embed loads a lot of player JavaScript even if nobody presses play. Chrome's Lighthouse documentation recommends a facade: a static preview image that swaps in the real player on click. Libraries such as lite-youtube-embed do this.

How to compress a video for the web

Compress the file before uploading to reduce video size. A phone or screen recording is often several times larger than it needs to be for the web.

A typical FFmpeg command for a web-friendly MP4:

ffmpeg -i input.mov -c:v libx264 -crf 28 -preset slow -movflags +faststart -an output.mp4

What each part does:

  • -crf 28 sets the quality. Higher numbers mean smaller files.
  • -movflags +faststart lets playback begin before the whole file downloads.
  • -an removes the audio track, for silent background clips.

Should you self-host videos or use YouTube?

For anything longer than a short clip, use a video platform (YouTube, Vimeo, Cloudflare Stream, Bunny Stream and similar). It handles adaptive streaming and multiple quality levels for you.

Self-hosting large videos on shared hosting can use up bandwidth quickly.

How to minify HTML, CSS and JavaScript

Minify CSS, JavaScript and HTML at build time (or with a plugin on WordPress) to reduce their file size, and turn on Brotli or gzip compression on the server or CDN.

What is the difference between minification and compression?

  • Minification removes characters the browser doesn't need: spaces, line breaks, comments and long variable names.
  • Compression (Brotli or gzip) is applied by the server when it sends the file.

Both reduce transfer size and they work together, but compression usually saves far more than minification alone. Lighthouse's documentation describes Brotli as more efficient than gzip, with gzip as the widely supported fallback.

How do you minify files on different kinds of sites?

  • Custom sites with a build step (Vite, webpack, Next.js, Astro and so on) minify CSS and JavaScript automatically in production builds. Make sure you deploy the production build, not the development one.
  • Plain HTML/CSS/JS sites can run tools such as Terser (JavaScript), cssnano or Lightning CSS (CSS) and html-minifier-terser (HTML) before uploading.
  • WordPress sites usually handle minification through a caching or optimization plugin.

Does Cloudflare still minify files?

No. Cloudflare used to offer an "Auto Minify" switch, but Cloudflare retired it in August 2024, so don't rely on it; minify at build time or with your plugin instead.

How do you check that compression is on?

Compression is normally a server or CDN setting, and many hosts and CDNs enable it by default. To check:

  1. Open Chrome DevTools and go to the Network tab.
  2. Reload the page and click a CSS or JS file.
  3. Look for content-encoding: br or gzip in the response headers.

How to eliminate render-blocking CSS and JavaScript

PageSpeed Insights reports this as "Eliminate render-blocking resources". The browser can't draw the page until it has downloaded and processed the CSS and synchronous scripts in the <head>.

Chrome's Lighthouse documentation counts a script as render-blocking when it is in the head without defer or async, and a stylesheet when it applies to the current screen. Here is how to fix each kind:

  • Scripts: add defer to scripts that aren't needed for the first paint, or async for independent scripts such as analytics. Move nothing critical behind user interaction.
  • CSS: inline the small amount of CSS needed for the above-the-fold content (critical CSS) and load the rest without blocking. Split print or large-screen styles into separate files with a media attribute.
  • Unused code: the Coverage tab in Chrome DevTools shows how much of each CSS and JS file is actually used on the page. Large unused percentages usually come from themes, page builders, and libraries loaded on every page "just in case".
  • Third-party scripts: chat widgets, heatmaps, multiple analytics tags, social embeds and A/B testing tools add up quickly. Audit them and keep only the ones that earn their cost.

How to load web fonts faster

Web fonts are a common hidden cost. To keep them light:

  • Use WOFF2 files.
  • Load only the weights and character sets you use.
  • Set font-display: swap so text is visible while the font loads.
  • Self-host fonts to avoid an extra connection to a third-party domain.
  • Preload the one or two fonts used above the fold.

Improve INP: when a page freezes on tap or click

A page can load quickly and still feel slow if it freezes when tapped. That is what INP measures.

The usual cause is JavaScript running in long tasks, which web.dev defines as anything that blocks the main thread for more than 50 milliseconds. To fix it:

  • Ship less JavaScript: remove unused libraries and heavy widgets.
  • Break long work into smaller chunks and yield to the browser between them (with scheduler.yield() where it is supported, or setTimeout as a fallback), so clicks and taps are handled in between.
  • Avoid doing expensive work directly in click and input handlers; show feedback first, then do the work.

Browser caching and CDNs: serve files from close by

Cache static files in the browser for a long time (often called "leverage browser caching"), and serve them from a CDN so they come from a server near each visitor. Both reduce load time, especially for repeat visits and for visitors far from your server.

How do you set browser caching?

Static files that rarely change (images, fonts, CSS, JS) should be cached by the browser for a long time, so repeat visits don't download them again.

The safe pattern is to give each file a versioned name (for example style.3f9a1c.css, which build tools do automatically) and send a long cache lifetime. When the file changes, its name changes, so visitors never get a stale copy.

How to set cache headers on cPanel (.htaccess)

On Apache hosting (most cPanel accounts), you can set this in the .htaccess of the folder that holds your static files:

<IfModule mod_headers.c>
  <FilesMatch "\.(webp|avif|jpg|jpeg|png|svg|gif|mp4|webm|woff2|css|js)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
  </FilesMatch>
</IfModule>

What does a CDN do?

A content delivery network keeps copies of your files on servers around the world and serves each visitor from the nearest one. That cuts the distance data travels and takes load off your own server.

Cloudflare, Bunny CDN, Fastly and Amazon CloudFront are common choices; Cloudflare's free plan is popular for small sites.

Does Cloudflare cache HTML pages?

Not by default. Cloudflare's documentation states that its CDN does not cache HTML by default. It caches static files by extension, including images (JPG, PNG, WebP, AVIF, SVG and others), CSS, JS and video files such as MP4 and WebM.

So with default settings, Cloudflare speeds up your assets, but every page request still goes to your server.

If your pages are static or rarely change, a Cache Rule can cache HTML too. Logged-in or personalized pages (carts, dashboards, WordPress admin) must not be cached.

You can check whether a file came from Cloudflare's cache in DevTools: the cf-cache-status response header shows HIT when it was served from cache, and MISS or DYNAMIC when it came from your server.

Should images be on a separate subdomain?

Some sites serve images and media from a subdomain such as assets.example.com or static.example.com. It can make sense for practical reasons:

  • keeping large media out of your code repository;
  • using cheaper storage for big files;
  • applying a separate caching policy.

It is not a speed trick on its own, though. Under HTTP/2 and HTTP/3, splitting files across many domains ("domain sharding") no longer helps, and each extra domain costs a DNS lookup and connection.

If you use an asset domain, keep it to one, put it behind the same CDN, and consider <link rel="preconnect"> for it when the LCP image comes from there.

How to reduce server response time (TTFB)

Time to First Byte is how long the browser waits before the first byte of the HTML arrives. Everything else on the page waits for it. PageSpeed Insights flags a slow one as "Reduce initial server response time".

web.dev suggests most sites aim for a TTFB of 0.8 seconds or less as a rough guide.

Slow TTFB usually comes from:

  • no page caching, so every visit rebuilds the page from the database;
  • overloaded or very cheap shared hosting;
  • an outdated PHP version (on PHP sites);
  • slow database queries or too many plugins running on each request;
  • the server being physically far from visitors with no CDN in front.

How to speed up a WordPress site

WordPress can be fast, but a typical install collects plugins, a heavy theme and a page builder over time. For WordPress speed optimization, work through these steps in rough order of impact:

  1. Add page caching. A caching plugin (for example WP Rocket, W3 Total Cache, WP Super Cache, or LiteSpeed Cache on LiteSpeed servers) stores finished pages so PHP and the database don't run on every visit. Use one caching plugin, not two; overlapping ones conflict.
  2. Audit plugins. Deactivate plugins one at a time and re-test. Sliders, social feeds, related-post plugins and all-in-one page builders are frequent offenders because they load scripts on every page.
  3. Choose a lightweight theme. Many multipurpose themes load large CSS and JS files everywhere. A lean theme or a block theme often loads far less.
  4. Use the image features WordPress already has. WordPress has added native lazy loading (5.5), automatic fetchpriority for the likely LCP image (6.3), and AVIF upload support (6.5, if your server's image library supports it). Check that a plugin isn't also lazy-loading the hero image, which undoes this.
  5. Keep PHP updated to a currently supported version offered by your host.
  6. Compress and convert uploads to WebP or AVIF, either before uploading (with the tools above) or with an image optimization plugin, to reduce image size across the media library.
  7. Put a CDN in front, and serve images and static files from it.
  8. Clean the database occasionally (old revisions, spam comments, expired transients). The effect is usually modest, so do this after the steps above.

Speed optimization for custom-coded and framework sites

On hand-built or framework sites (React, Next.js, Vue, Laravel and so on), you control more, so the levers are different:

  • Pre-render pages as static HTML where possible (static site generation or server rendering) rather than building the main content in the browser with JavaScript. Static HTML from a CDN is the fastest thing you can serve.
  • Split JavaScript by route so each page only loads the code it needs, and check bundle size with an analyzer (for example webpack-bundle-analyzer or the equivalent for your bundler).
  • Preload the LCP resource if the browser would otherwise discover it late (for example a hero image set in CSS).
  • Watch hydration cost. A page can render fast but stay unresponsive while a large JavaScript bundle hydrates, which shows up as poor INP.
  • Process images in your pipeline, not by hand: generate WebP/AVIF and responsive sizes at build time or through an image CDN, and still set dimensions on every image.

Common website speed mistakes to avoid

  • Lazy-loading the hero image, which delays LCP.
  • Installing several "speed" plugins that minify, combine and lazy-load the same files and break each other.
  • Chasing a perfect Lighthouse score instead of improving field data and real load time.
  • Adding a CDN without cache headers, so files are fetched from the origin every time.
  • Uploading full-resolution camera photos and letting CSS shrink them.
  • Autoplaying large background videos and image sliders above the fold.
  • Testing only on a fast desktop connection.

Frequently asked questions

Does page speed affect SEO?

Yes, but as one factor among many. Google's Search Central documentation "highly recommends" good Core Web Vitals for success in Search and says they align with what its core ranking systems aim to reward.

Relevance and content quality still matter more. A fast page with weak content won't outrank a slower page that answers the query much better.

What is a good page load time?

There isn't one official "load time" number. The practical targets are the Core Web Vitals thresholds: LCP of 2.5 seconds or less, INP of 200 ms or less and CLS of 0.1 or less, for at least 75% of visits.

Is minifying CSS and JavaScript enough to make a site fast?

Rarely. Minification helps, but images, video, third-party scripts and server response time usually matter much more. Treat minification as a standard step, not the main fix.

Does a CDN always make a site faster?

It almost always helps static files load faster for visitors far from your server. It won't fix a slow server for uncached HTML, heavy JavaScript, or oversized images; those need to be fixed at the source.

How often should I test site speed?

Test after any significant change (new theme, plugin, script or design) and check field data in PageSpeed Insights or Search Console's Core Web Vitals report every month or so, since field data covers the previous 28 days.

Found this useful? Share it with someone who runs a website.

Share this article