.htaccess Generator for WordPress

Cache & Performance Guide

JA

Why Manage Security Settings and Caching Together

Configuring HTTPS and caching together is efficient. Both can be managed in .htaccess , so handling them in one place reduces maintenance overhead.

Security plugins such as Wordfence scan every request, which can affect site performance. Caching and performance optimizations help offset that cost.


Gzip Compression ( mod_deflate )

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/css
    AddOutputFilterByType DEFLATE application/javascript application/json
    AddOutputFilterByType DEFLATE application/xml text/xml image/svg+xml
    AddOutputFilterByType DEFLATE font/woff font/woff2
</IfModule>

Role and Effect

Text-based files (HTML, CSS, JavaScript, JSON, etc.) are compressed on the server before being sent to the browser. This significantly reduces transfer size and improves page load speed.

Choosing MIME Types to Compress

MIME Type File Type Compression Benefit
text/html HTML pages High (text-based)
text/css Stylesheets High
application/javascript JavaScript High
application/json JSON data High
image/svg+xml SVG images High (XML text)
font/woff2 Web fonts Low (already compressed)

Image formats such as JPEG, PNG, and WebP are already compressed, so there is no need to Gzip them. The benefit is minimal while CPU usage increases.


Browser Caching ( Cache-Control )

<IfModule mod_headers.c>
    # Images, fonts, icons (1-year cache + immutable)
    <FilesMatch "\.(ico|jpg|jpeg|png|gif|webp|svg|woff|woff2|ttf)$">
        Header always set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>

    # CSS and JavaScript (1-year cache + immutable)
    <FilesMatch "\.(css|js)$">
        Header always set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>

    # HTML, JSON, XML (no caching)
    <FilesMatch "\.(html|htm|json|xml)$">
        Header always set Cache-Control "no-store, no-cache, must-revalidate"
    </FilesMatch>
</IfModule>

Cache Lifetime by File Type

File Type Recommended Setting Reason
Images, fonts, CSS, JS 1 year (31536000 seconds) Static files that change infrequently
HTML, JSON, XML No caching Dynamically generated content by WordPress

The immutable Flag

Within the max-age period, the browser skips conditional GET revalidation requests entirely. The browser treats the file as guaranteed unchanged until expiry and serves it from cache without contacting the server.

Using immutable requires cache busting — include a version number or hash in CSS and JS filenames. WordPress plugins and themes typically use query strings ( ?ver=6.0 ) for versioning, so this is not an issue.

Why HTML / JSON / XML Should Not Be Cached

HTML generated by WordPress is dynamic content that can change with every post, comment, or plugin configuration. Caching it risks serving stale content, so no-store disables caching entirely.


Disabling ETag

FileETag None

Role and Benefits

An ETag is an identifier used to detect file changes. When Cache-Control expiry is already configured, ETag-based revalidation becomes redundant.

The main benefits of disabling ETags are:

  • Eliminates redundant If-None-Match requests, reducing server load
  • In multi-server environments (e.g. load balancers), ETag values can differ between servers and may not work correctly — disabling them avoids this issue

Adding MIME Types ( mime_module )

<IfModule mime_module>
    AddType image/x-icon        .ico
    AddType image/svg+xml       .svg
    AddType font/woff            .woff
    AddType font/woff2           .woff2
    AddType application/font-ttf .ttf
</IfModule>

Role

This configuration ensures Apache correctly identifies file types and sends the appropriate Content-Type header to the browser. Without correct MIME types:

  • Browsers may treat font files as plain text, causing load failures
  • SVG files may not render as images
  • Browsers may throw CORS errors, especially for web fonts

Older versions of Apache may not define .woff2 or .webp by default, so adding them explicitly is a safe practice.


About Keep-Alive

Role

HTTP persistent connections (Keep-Alive) allow multiple requests to be handled over a single TCP connection. Without it, each file — HTML, CSS, JS, images — requires a separate TCP connection. Keep-Alive reduces the overhead of establishing and closing connections (TCP handshake), improving page load speed.

Cannot Be Controlled via .htaccess

Keep-Alive is determined by Apache server configuration ( httpd.conf or apache2.conf ). Because Connection is a hop-by-hop header, setting Header always set Connection "keep-alive" in .htaccess has no effect on enabling Keep-Alive.

To control it at the server level, use directives like:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

Most shared hosting providers (e.g. XServer) have Keep-Alive enabled by default, so no individual configuration is needed.

In HTTP/2 and later, connection multiplexing is built in as a standard feature, so Keep-Alive settings primarily affect HTTP/1.1 connections only.

← Back to Generator