Page speed directly affects user experience, conversion rates, and search rankings. In 2026, optimizing for Core Web Vitals—Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS)—remains critical. This guide walks through tactical improvements you can implement on your hosting stack, from compression and caching to database tuning and CDN configuration.
Measure Before You Optimize
Before making changes, establish a baseline. Use these tools to identify bottlenecks:
- PageSpeed Insights: Provides field and lab data with Core Web Vitals scores
- WebPageTest: Offers detailed waterfall charts and filmstrip views
- Lighthouse: Built into Chrome DevTools for on-demand audits
- Server logs: Check TTFB (Time to First Byte) from your access logs
Focus on real-user metrics (field data) over synthetic tests when possible. A page that scores well in lab conditions but fails for actual visitors needs real-world optimization.
Enable Compression
Text-based assets—HTML, CSS, JavaScript, JSON, XML—compress well. Compression reduces transfer size by 70-90% for these resources.
Gzip vs Brotli
Most servers support Gzip. Brotli offers better compression ratios and is widely supported by modern browsers. If your server supports it, enable Brotli for static assets.
Apache (with mod_deflate for Gzip):
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json application/xml
</IfModule>
Nginx (Gzip):
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;
gzip_min_length 1000;
gzip_comp_level 6;
Nginx (Brotli):
Requires the ngx_brotli module:
brotli on;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;
brotli_comp_level 6;
Verify compression with:
curl -H "Accept-Encoding: gzip" -I https://yourdomain.com
Look for Content-Encoding: gzip or Content-Encoding: br in the response headers.
Optimize Images
Images typically account for the majority of page weight. Optimization involves format selection, compression, sizing, and delivery strategy.
Choose Modern Formats
- WebP: Offers superior compression compared to JPEG and PNG. Widely supported.
- AVIF: Even better compression than WebP, but encoding is slower and support is still growing.
Serve modern formats with fallbacks using the <picture> element:
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Description" loading="lazy">
</picture>
Implement Lazy Loading
Native lazy loading defers offscreen images until the user scrolls near them:
<img src="image.jpg" alt="Description" loading="lazy">
This works for images and iframes. For background images or more complex scenarios, use Intersection Observer API or a JavaScript library.
Resize and Compress
Serve images at the display size, not camera resolution. A 4000×3000 image displayed at 800×600 wastes bandwidth.
Use command-line tools for batch optimization:
# WebP conversion
cwebp -q 80 input.jpg -o output.webp
# JPEG optimization
jpegoptim --max=85 --strip-all *.jpg
# PNG optimization
optipng -o2 *.png
For WordPress, plugins like ShortPixel, Imagify, or EWWW Image Optimizer automate this process.
Specify Width and Height
Always set explicit dimensions to prevent layout shifts:
<img src="image.jpg" alt="Description" width="800" height="600" loading="lazy">
This reserves space in the layout before the image loads, improving CLS.
Leverage Browser Caching
Set cache headers to instruct browsers to store static assets locally.
Apache (.htaccess):
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
</IfModule>
Nginx:
location ~* \.(jpg|jpeg|png|webp|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location ~* \.(css|js)$ {
expires 1M;
add_header Cache-Control "public";
}
Use versioned filenames (e.g., style.v2.css or query strings style.css?v=2) to bust cache when files change.
Minify CSS and JavaScript
Minification removes whitespace, comments, and shortens variable names. This reduces file size by 20-40%.
Build-time minification is preferred. Use build tools:
- Webpack: Built-in optimization in production mode
- Vite: Automatic minification
- Terser: Standalone JavaScript minifier
- cssnano: CSS minifier
For WordPress, caching plugins (WP Rocket, W3 Total Cache, Autoptimize) handle minification.
Eliminate Render-Blocking Resources
CSS blocks rendering by default. Inline critical CSS and defer non-critical styles:
<style>
/* Critical CSS inline */
body { margin: 0; font-family: sans-serif; }
</style>
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
For JavaScript, use defer or async:
<script src="script.js" defer></script>
defer: Downloads in parallel, executes after HTML parsingasync: Downloads in parallel, executes immediately when ready
Use defer for scripts that depend on DOM or other scripts. Use async for independent scripts like analytics.
Use a CDN
A Content Delivery Network caches your content on edge servers worldwide, reducing latency for geographically distributed visitors.
CDN Options
- Cloudflare: Free tier with global PoPs, includes DDoS protection and SSL
- KeyCDN: Affordable, pay-as-you-go pricing
- BunnyCDN: Low-cost with good performance
- Amazon CloudFront: Integrated with AWS services
- Fastly: Real-time purging and advanced configuration
CDN Configuration Checklist
- Point DNS to CDN: Update A/AAAA or CNAME records
- Enable caching: Configure cache rules for static assets
- Set cache TTL: Balance freshness and hit rate (1 hour to 1 year depending on content)
- Enable HTTP/3: If your CDN supports QUIC, enable it for better performance over lossy networks
- Configure purging: Set up cache invalidation for content updates
- Monitor cache hit rate: Aim for 90%+ hit rate for static assets
For WordPress, use plugins like W3 Total Cache or WP Rocket to integrate CDN URLs automatically.
Optimize Your Database
Database queries can bottleneck dynamic pages, especially on WordPress sites with large post counts or many plugins.
WordPress Database Optimization
Clean up revisions and transients:
-- Delete post revisions (keep latest 5)
DELETE FROM wp_posts WHERE post_type = 'revision';
-- Clear expired transients
DELETE FROM wp_options WHERE option_name LIKE '_transient_%';
Use WP-CLI for safer cleanup:
wp post delete $(wp post list --post_type='revision' --format=ids) --force
wp transient delete --all
Optimize tables:
OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options;
Or via WP-CLI:
wp db optimize
Index Critical Columns
Slow queries often result from missing indexes. Check your slow query log and add indexes where needed.
SHOW INDEX FROM wp_posts;
WordPress core tables are indexed by default, but custom queries or plugin tables may need optimization.
Use Object Caching
Object caching (Redis or Memcached) stores database query results in memory, drastically reducing query load.
Install Redis:
# On Ubuntu/Debian
sudo apt install redis-server
sudo systemctl enable redis-server
WordPress Redis plugin:
Install the Redis Object Cache plugin and add to wp-config.php:
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);
Activate from WordPress admin or via WP-CLI:
wp plugin install redis-cache --activate
wp redis enable
Reduce Server Response Time (TTFB)
Time to First Byte measures how quickly your server responds. Target under 200ms for good LCP.
Enable OPcache
PHP OPcache stores compiled bytecode in memory, eliminating repeated compilation overhead.
Verify it's enabled:
php -i | grep opcache.enable
If not enabled, add to php.ini:
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
Restart PHP-FPM:
sudo systemctl restart php8.2-fpm
Tune PHP-FPM
Adjust worker processes based on available RAM:
; /etc/php/8.2/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
Monitor with:
sudo systemctl status php8.2-fpm
Upgrade PHP Version
Newer PHP versions are significantly faster. PHP 8.1+ includes JIT compilation and performance improvements over PHP 7.x. Check compatibility with your CMS and plugins before upgrading.
Implement HTTP/2 or HTTP/3
HTTP/2 multiplexes requests over a single connection, reducing overhead. HTTP/3 uses QUIC for even better performance over unreliable networks.
Nginx HTTP/2:
listen 443 ssl http2;
Nginx HTTP/3 (with QUIC module):
listen 443 quic reuseport;
listen 443 ssl http2;
ssl_protocols TLSv1.3;
add_header Alt-Svc 'h3=":443"; ma=86400';
Apache HTTP/2:
Requires mod_http2:
LoadModule http2_module modules/mod_http2.so
Protocols h2 h2c http/1.1
Verify with:
curl -I --http2 https://yourdomain.com
Preload and Prefetch Critical Resources
Resource hints instruct the browser to load critical assets earlier.
<!-- Preload critical CSS/JS/fonts -->
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
<!-- Prefetch next-page resources -->
<link rel="prefetch" href="next-page.html">
<!-- Preconnect to third-party domains -->
<link rel="preconnect" href="https://fonts.googleapis.com">
Use sparingly—preloading too many resources can backfire.
Monitor Core Web Vitals
Track real-user metrics over time:
- Google Search Console: Shows Core Web Vitals for your pages
- Chrome User Experience Report (CrUX): Field data from actual Chrome users
- RUM (Real User Monitoring): Tools like SpeedCurve, Cloudflare Web Analytics, or New Relic
Core Web Vitals Targets
- LCP: < 2.5s (Largest Contentful Paint)
- INP: < 200ms (Interaction to Next Paint)
- CLS: < 0.1 (Cumulative Layout Shift)
Aim for the 75th percentile of users to meet these thresholds.
Conclusion
Page speed optimization is not a one-time task—it requires ongoing monitoring and adjustment as content and traffic patterns change. Start with compression and caching for quick wins, then tackle image optimization and database tuning. Implement a CDN if you serve a global audience. Measure real-user metrics with Core Web Vitals, and prioritize fixes that impact the largest number of visitors. Small improvements compound over time, resulting in faster pages, better conversions, and higher search rankings.
