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
immutablerequires 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-Matchrequests, 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.