I’ll build a strong performance/cache-headers.php file for your RX theme that adds cache-control, security-friendly headers, CDN/proxy support, static asset caching, HTML no-cache rules for logged-in users, and safe hooks for WordPress.
Below is an advanced rx-theme/inc/performance/cache-headers.php file for your RX Theme.
Create this file:
rx-theme/
└── inc/
└── performance/
└── cache-headers.php
Then include it from functions.php:
require_once get_template_directory() . '/inc/performance/cache-headers.php';
performance/cache-headers.php
<?php
/**
* RX Theme - Advanced Performance Cache Headers
*
* File: inc/performance/cache-headers.php
*
* Purpose:
* - Add browser cache headers
* - Add CDN/proxy cache headers
* - Add static asset cache rules
* - Avoid caching admin, login, preview, REST write requests, WooCommerce cart/checkout
* - Add ETag/Last-Modified helpers
* - Add security-friendly performance headers
* - Add resource hint support
* - Add server-side output cache-control rules
*
* Important:
* - PHP can only send headers before output starts.
* - For best static asset caching, also configure .htaccess / Nginx / CDN.
*/
defined('ABSPATH') || exit;
if (!class_exists('RX_Theme_Cache_Headers')) :
final class RX_Theme_Cache_Headers {
/**
* Version for debugging and cache identification.
*/
const VERSION = '1.0.0';
/**
* Default cache TTL values in seconds.
*/
const TTL_HTML_PUBLIC = 300; // 5 minutes
const TTL_HTML_SWR = 600; // 10 minutes stale-while-revalidate
const TTL_HTML_SIE = 86400; // 1 day stale-if-error
const TTL_FEED = 1800; // 30 minutes
const TTL_REST_GET = 300; // 5 minutes
const TTL_STATIC_SHORT = 86400; // 1 day
const TTL_STATIC_MEDIUM = 604800; // 7 days
const TTL_STATIC_LONG = 31536000; // 1 year
const TTL_SITEMAP = 3600; // 1 hour
const TTL_ROBOTS = 86400; // 1 day
/**
* Start hooks.
*/
public static function init() {
add_action('send_headers', array(__CLASS__, 'send_dynamic_cache_headers'), 1);
add_action('template_redirect', array(__CLASS__, 'maybe_send_conditional_headers'), 0);
add_filter('wp_headers', array(__CLASS__, 'filter_wp_headers'), 10, 2);
add_filter('nocache_headers', array(__CLASS__, 'filter_nocache_headers'), 10, 1);
add_filter('mod_rewrite_rules', array(__CLASS__, 'add_htaccess_cache_rules'));
add_filter('robots_txt', array(__CLASS__, 'robots_txt_cache_note'), 10, 2);
add_filter('wp_resource_hints', array(__CLASS__, 'resource_hints'), 10, 2);
add_action('wp_head', array(__CLASS__, 'add_dns_prefetch_meta'), 1);
add_action('wp_head', array(__CLASS__, 'add_cache_debug_meta'), 2);
add_action('init', array(__CLASS__, 'maybe_handle_static_asset_request'), 0);
}
/**
* Main dynamic header manager.
*/
public static function send_dynamic_cache_headers() {
if (headers_sent()) {
return;
}
if (self::is_cache_bypass_request()) {
self::send_no_store_headers('bypass-request');
return;
}
if (self::is_admin_like_request()) {
self::send_no_store_headers('admin-like-request');
return;
}
if (self::is_user_specific_request()) {
self::send_private_no_cache_headers('user-specific-request');
return;
}
if (self::is_sensitive_ecommerce_request()) {
self::send_no_store_headers('sensitive-ecommerce-request');
return;
}
if (is_robots()) {
self::send_public_cache_headers(self::TTL_ROBOTS, self::TTL_ROBOTS, self::TTL_ROBOTS, 'robots');
return;
}
if (self::is_sitemap_request()) {
self::send_public_cache_headers(self::TTL_SITEMAP, self::TTL_SITEMAP, self::TTL_SITEMAP, 'sitemap');
return;
}
if (is_feed()) {
self::send_public_cache_headers(self::TTL_FEED, self::TTL_FEED, self::TTL_HTML_SIE, 'feed');
return;
}
if (self::is_rest_get_request()) {
self::send_public_cache_headers(self::TTL_REST_GET, self::TTL_REST_GET, self::TTL_HTML_SIE, 'rest-get');
return;
}
if (is_404() || is_search()) {
self::send_private_no_cache_headers('search-or-404');
return;
}
if (is_front_page() || is_home() || is_singular() || is_archive() || is_page()) {
self::send_public_cache_headers(
self::TTL_HTML_PUBLIC,
self::TTL_HTML_SWR,
self::TTL_HTML_SIE,
'html-public'
);
self::send_last_modified_for_wp_query();
return;
}
self::send_public_cache_headers(
self::TTL_HTML_PUBLIC,
self::TTL_HTML_SWR,
self::TTL_HTML_SIE,
'html-default'
);
}
/**
* Modify WordPress headers before output.
*/
public static function filter_wp_headers($headers, $wp) {
if (!is_array($headers)) {
$headers = array();
}
$headers['X-RX-Theme-Cache'] = 'enabled';
$headers['X-RX-Cache-Version'] = self::VERSION;
if (!isset($headers['X-Content-Type-Options'])) {
$headers['X-Content-Type-Options'] = 'nosniff';
}
if (!isset($headers['Referrer-Policy'])) {
$headers['Referrer-Policy'] = 'strict-origin-when-cross-origin';
}
if (!isset($headers['X-Frame-Options']) && !self::is_customize_preview_safe()) {
$headers['X-Frame-Options'] = 'SAMEORIGIN';
}
if (!isset($headers['Permissions-Policy'])) {
$headers['Permissions-Policy'] = 'camera=(), microphone=(), geolocation=(), interest-cohort=()';
}
return $headers;
}
/**
* Improve WordPress no-cache headers.
*/
public static function filter_nocache_headers($headers) {
if (!is_array($headers)) {
$headers = array();
}
$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0, private';
$headers['Pragma'] = 'no-cache';
$headers['Expires'] = 'Wed, 11 Jan 1984 05:00:00 GMT';
$headers['X-RX-Cache'] = 'no-cache';
return $headers;
}
/**
* Public CDN/browser cache headers.
*/
private static function send_public_cache_headers($max_age, $swr = 0, $sie = 0, $reason = 'public') {
if (headers_sent()) {
return;
}
$max_age = absint($max_age);
$swr = absint($swr);
$sie = absint($sie);
$cache_control = array(
'public',
'max-age=' . $max_age,
);
if ($swr > 0) {
$cache_control[] = 'stale-while-revalidate=' . $swr;
}
if ($sie > 0) {
$cache_control[] = 'stale-if-error=' . $sie;
}
header('Cache-Control: ' . implode(', ', $cache_control), true);
header('Surrogate-Control: max-age=' . $max_age, true);
header('CDN-Cache-Control: public, max-age=' . $max_age, true);
header('Cloudflare-CDN-Cache-Control: public, max-age=' . $max_age, true);
header('X-RX-Cache: HIT-ELIGIBLE; reason=' . sanitize_key($reason), true);
self::send_common_performance_headers();
}
/**
* Private but not full no-store.
*/
private static function send_private_no_cache_headers($reason = 'private') {
if (headers_sent()) {
return;
}
header('Cache-Control: private, no-cache, must-revalidate, max-age=0', true);
header('Pragma: no-cache', true);
header('Expires: Wed, 11 Jan 1984 05:00:00 GMT', true);
header('X-RX-Cache: PRIVATE; reason=' . sanitize_key($reason), true);
self::send_common_performance_headers();
}
/**
* Strict no-store for admin, login, preview, cart, checkout, nonce pages.
*/
private static function send_no_store_headers($reason = 'no-store') {
if (headers_sent()) {
return;
}
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0, private', true);
header('Pragma: no-cache', true);
header('Expires: Wed, 11 Jan 1984 05:00:00 GMT', true);
header('X-RX-Cache: BYPASS; reason=' . sanitize_key($reason), true);
self::send_common_performance_headers();
}
/**
* Common safe performance headers.
*/
private static function send_common_performance_headers() {
if (headers_sent()) {
return;
}
header('X-Content-Type-Options: nosniff', false);
header('Referrer-Policy: strict-origin-when-cross-origin', false);
header('Permissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=()', false);
header('X-RX-Theme: cache-headers', false);
if (!self::is_customize_preview_safe()) {
header('X-Frame-Options: SAMEORIGIN', false);
}
if (is_ssl()) {
header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload', false);
}
}
/**
* Send Last-Modified header based on queried posts.
*/
private static function send_last_modified_for_wp_query() {
if (headers_sent()) {
return;
}
global $wp_query;
if (empty($wp_query) || empty($wp_query->posts) || !is_array($wp_query->posts)) {
return;
}
$last_modified = 0;
foreach ($wp_query->posts as $post) {
if (!empty($post->post_modified_gmt)) {
$modified = strtotime($post->post_modified_gmt . ' GMT');
if ($modified > $last_modified) {
$last_modified = $modified;
}
}
}
if ($last_modified > 0) {
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified) . ' GMT', true);
$etag = '"' . md5(home_url(add_query_arg(array(), $_SERVER['REQUEST_URI'] ?? '')) . '|' . $last_modified . '|' . self::VERSION) . '"';
header('ETag: ' . $etag, true);
}
}
/**
* Conditional 304 support.
*/
public static function maybe_send_conditional_headers() {
if (headers_sent()) {
return;
}
if (self::is_cache_bypass_request() || is_user_logged_in()) {
return;
}
global $wp_query;
if (empty($wp_query) || empty($wp_query->posts) || !is_array($wp_query->posts)) {
return;
}
$last_modified = 0;
foreach ($wp_query->posts as $post) {
if (!empty($post->post_modified_gmt)) {
$modified = strtotime($post->post_modified_gmt . ' GMT');
if ($modified > $last_modified) {
$last_modified = $modified;
}
}
}
if ($last_modified <= 0) {
return;
}
$etag = '"' . md5(home_url(add_query_arg(array(), $_SERVER['REQUEST_URI'] ?? '')) . '|' . $last_modified . '|' . self::VERSION) . '"';
$if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
? strtotime(stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']))
: false;
$if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH'])
? trim(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']))
: false;
$etag_match = $if_none_match && $if_none_match === $etag;
$time_match = $if_modified_since && $if_modified_since >= $last_modified;
if ($etag_match || $time_match) {
status_header(304);
header('ETag: ' . $etag, true);
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $last_modified) . ' GMT', true);
header('Cache-Control: public, max-age=' . self::TTL_HTML_PUBLIC . ', stale-while-revalidate=' . self::TTL_HTML_SWR, true);
exit;
}
}
/**
* Detect request types that must bypass cache.
*/
private static function is_cache_bypass_request() {
if (defined('DONOTCACHEPAGE') && DONOTCACHEPAGE) {
return true;
}
if (defined('REST_REQUEST') && REST_REQUEST && !self::is_rest_get_request()) {
return true;
}
if (is_preview() || is_customize_preview()) {
return true;
}
if (self::request_has_query_bypass()) {
return true;
}
if (self::request_method_is_unsafe()) {
return true;
}
if (self::has_auth_cookies()) {
return true;
}
return false;
}
/**
* Admin/login/ajax/customizer pages.
*/
private static function is_admin_like_request() {
if (is_admin()) {
return true;
}
if (wp_doing_ajax()) {
return true;
}
if (wp_doing_cron()) {
return true;
}
$uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
$admin_paths = array(
'/wp-admin',
'/wp-login.php',
'/wp-register.php',
'/xmlrpc.php',
'/wp-json/wp/v2/users/me',
);
foreach ($admin_paths as $path) {
if (stripos($uri, $path) !== false) {
return true;
}
}
return false;
}
/**
* Logged-in or personalized pages.
*/
private static function is_user_specific_request() {
if (is_user_logged_in()) {
return true;
}
if (is_author()) {
return false;
}
$cookies = array_keys($_COOKIE);
$private_cookie_patterns = array(
'wordpress_logged_in_',
'wp-postpass_',
'comment_author_',
'woocommerce_items_in_cart',
'woocommerce_cart_hash',
'wp_woocommerce_session_',
'edd_items_in_cart',
'rx_private_',
);
foreach ($cookies as $cookie_name) {
foreach ($private_cookie_patterns as $pattern) {
if (stripos($cookie_name, $pattern) === 0 || stripos($cookie_name, $pattern) !== false) {
return true;
}
}
}
return false;
}
/**
* WooCommerce / Easy Digital Downloads sensitive pages.
*/
private static function is_sensitive_ecommerce_request() {
if (function_exists('is_cart') && is_cart()) {
return true;
}
if (function_exists('is_checkout') && is_checkout()) {
return true;
}
if (function_exists('is_account_page') && is_account_page()) {
return true;
}
if (function_exists('edd_is_checkout') && edd_is_checkout()) {
return true;
}
if (function_exists('edd_is_success_page') && edd_is_success_page()) {
return true;
}
if (function_exists('edd_is_failed_transaction_page') && edd_is_failed_transaction_page()) {
return true;
}
return false;
}
/**
* REST GET can be cached briefly.
*/
private static function is_rest_get_request() {
if (!(defined('REST_REQUEST') && REST_REQUEST)) {
return false;
}
$method = isset($_SERVER['REQUEST_METHOD']) ? strtoupper(sanitize_text_field(wp_unslash($_SERVER['REQUEST_METHOD']))) : 'GET';
return $method === 'GET';
}
/**
* Unsafe methods should never be cached.
*/
private static function request_method_is_unsafe() {
$method = isset($_SERVER['REQUEST_METHOD']) ? strtoupper(sanitize_text_field(wp_unslash($_SERVER['REQUEST_METHOD']))) : 'GET';
return in_array($method, array('POST', 'PUT', 'PATCH', 'DELETE'), true);
}
/**
* Cache bypass query strings.
*/
private static function request_has_query_bypass() {
$bypass_keys = array(
'preview',
'customize_changeset_uuid',
'customize_theme',
'doing_wp_cron',
'nocache',
'no_cache',
'cache_bypass',
'elementor-preview',
'bricks',
'oxygen_iframe',
'fl_builder',
'et_fb',
'vc_editable',
'rx_no_cache',
);
foreach ($bypass_keys as $key) {
if (isset($_GET[$key])) {
return true;
}
}
return false;
}
/**
* Authentication cookies.
*/
private static function has_auth_cookies() {
if (empty($_COOKIE) || !is_array($_COOKIE)) {
return false;
}
foreach (array_keys($_COOKIE) as $cookie_name) {
if (
stripos($cookie_name, 'wordpress_logged_in_') !== false ||
stripos($cookie_name, 'wordpress_sec_') !== false ||
stripos($cookie_name, 'wp-settings-') !== false
) {
return true;
}
}
return false;
}
/**
* Detect sitemap.
*/
private static function is_sitemap_request() {
$uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
if (stripos($uri, 'sitemap') !== false && preg_match('/\.xml(\.gz)?($|\?)/i', $uri)) {
return true;
}
if (function_exists('wp_sitemaps_get_server') && get_query_var('sitemap')) {
return true;
}
return false;
}
/**
* Customizer needs frame access.
*/
private static function is_customize_preview_safe() {
return is_customize_preview() || isset($_GET['customize_changeset_uuid']);
}
/**
* Handle direct static asset requests if PHP receives them.
*
* Usually Apache/Nginx/CDN handles static files before PHP.
* This is useful for custom routing or PHP-served assets.
*/
public static function maybe_handle_static_asset_request() {
if (headers_sent()) {
return;
}
$uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
if (!$uri) {
return;
}
$path = parse_url($uri, PHP_URL_PATH);
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
if (!$ext) {
return;
}
$long_cache = array(
'css',
'js',
'mjs',
'json',
'map',
'jpg',
'jpeg',
'png',
'gif',
'webp',
'avif',
'svg',
'ico',
'woff',
'woff2',
'ttf',
'otf',
'eot',
'mp4',
'webm',
'ogg',
'mp3',
'wav',
'pdf',
);
if (!in_array($ext, $long_cache, true)) {
return;
}
$ttl = self::TTL_STATIC_LONG;
if (in_array($ext, array('json', 'map'), true)) {
$ttl = self::TTL_STATIC_MEDIUM;
}
if (in_array($ext, array('html', 'xml'), true)) {
$ttl = self::TTL_STATIC_SHORT;
}
header('Cache-Control: public, max-age=' . $ttl . ', immutable', true);
header('CDN-Cache-Control: public, max-age=' . $ttl, true);
header('X-RX-Static-Cache: enabled; ext=' . sanitize_key($ext), true);
self::send_static_content_type_header($ext);
self::send_common_performance_headers();
}
/**
* Static asset content type helper.
*/
private static function send_static_content_type_header($ext) {
$types = array(
'css' => 'text/css; charset=UTF-8',
'js' => 'application/javascript; charset=UTF-8',
'mjs' => 'application/javascript; charset=UTF-8',
'json' => 'application/json; charset=UTF-8',
'map' => 'application/json; charset=UTF-8',
'svg' => 'image/svg+xml; charset=UTF-8',
'webp' => 'image/webp',
'avif' => 'image/avif',
'png' => 'image/png',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'gif' => 'image/gif',
'ico' => 'image/x-icon',
'woff' => 'font/woff',
'woff2' => 'font/woff2',
'ttf' => 'font/ttf',
'otf' => 'font/otf',
'eot' => 'application/vnd.ms-fontobject',
'pdf' => 'application/pdf',
'mp4' => 'video/mp4',
'webm' => 'video/webm',
'ogg' => 'audio/ogg',
'mp3' => 'audio/mpeg',
'wav' => 'audio/wav',
);
if (isset($types[$ext])) {
header('Content-Type: ' . $types[$ext], false);
}
}
/**
* Resource hints: dns-prefetch / preconnect.
*/
public static function resource_hints($urls, $relation_type) {
if (!is_array($urls)) {
$urls = array();
}
$dns_prefetch = array(
'//fonts.googleapis.com',
'//fonts.gstatic.com',
'//www.googletagmanager.com',
'//www.google-analytics.com',
'//cdn.jsdelivr.net',
'//cdnjs.cloudflare.com',
'//unpkg.com',
);
$preconnect = array(
'https://fonts.gstatic.com',
'https://fonts.googleapis.com',
);
if ('dns-prefetch' === $relation_type) {
$urls = array_merge($urls, $dns_prefetch);
}
if ('preconnect' === $relation_type) {
$urls = array_merge($urls, $preconnect);
}
return array_values(array_unique($urls));
}
/**
* Extra DNS meta output.
*/
public static function add_dns_prefetch_meta() {
if (is_admin()) {
return;
}
echo "\n<!-- RX Theme Performance Resource Hints -->\n";
echo '<link rel="dns-prefetch" href="//fonts.googleapis.com">' . "\n";
echo '<link rel="dns-prefetch" href="//fonts.gstatic.com">' . "\n";
echo '<link rel="dns-prefetch" href="//www.googletagmanager.com">' . "\n";
echo '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>' . "\n";
}
/**
* Optional debug meta.
*/
public static function add_cache_debug_meta() {
if (!defined('WP_DEBUG') || !WP_DEBUG) {
return;
}
if (is_admin()) {
return;
}
echo "\n" . '<meta name="rx-cache-headers" content="enabled; version=' . esc_attr(self::VERSION) . '">' . "\n";
}
/**
* Add .htaccess rules when WordPress regenerates rewrite rules.
*
* Important:
* This only works on Apache with mod_rewrite and mod_expires/mod_headers enabled.
*/
public static function add_htaccess_cache_rules($rules) {
$rx_rules = self::get_apache_cache_rules();
if (strpos($rules, '# BEGIN RX Theme Cache Headers') !== false) {
return $rules;
}
return $rx_rules . "\n\n" . $rules;
}
/**
* Apache cache rules text.
*/
private static function get_apache_cache_rules() {
return <<<HTACCESS
# BEGIN RX Theme Cache Headers
<IfModule mod_expires.c>
ExpiresActive On
# Images
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/avif "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
# Fonts
ExpiresByType font/woff "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/ttf "access plus 1 year"
ExpiresByType font/otf "access plus 1 year"
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
# CSS and JavaScript
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
ExpiresByType application/x-javascript "access plus 1 year"
# Media
ExpiresByType video/mp4 "access plus 1 year"
ExpiresByType video/webm "access plus 1 year"
ExpiresByType audio/mpeg "access plus 1 year"
ExpiresByType audio/ogg "access plus 1 year"
ExpiresByType audio/wav "access plus 1 year"
# Documents
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType application/json "access plus 7 days"
ExpiresByType application/xml "access plus 1 hour"
ExpiresByType text/xml "access plus 1 hour"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\\.(css|js|mjs|jpg|jpeg|png|gif|webp|avif|svg|ico|woff|woff2|ttf|otf|eot|mp4|webm|ogg|mp3|wav)$">
Header set Cache-Control "public, max-age=31536000, immutable"
Header unset Pragma
Header unset ETag
</FilesMatch>
<FilesMatch "\\.(json|map)$">
Header set Cache-Control "public, max-age=604800"
</FilesMatch>
<FilesMatch "\\.(xml|txt)$">
Header set Cache-Control "public, max-age=3600"
</FilesMatch>
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"
<IfModule mod_setenvif.c>
SetEnvIfNoCase Request_URI "\\.(?:gif|jpe?g|png|webp|avif|svg|ico|css|js|mjs|woff2?|ttf|otf|eot|mp4|webm|ogg|mp3|wav)$" RX_STATIC_ASSET
Header set X-RX-Static-Cache "apache" env=RX_STATIC_ASSET
</IfModule>
</IfModule>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/plain
AddOutputFilterByType BROTLI_COMPRESS text/html
AddOutputFilterByType BROTLI_COMPRESS text/xml
AddOutputFilterByType BROTLI_COMPRESS text/css
AddOutputFilterByType BROTLI_COMPRESS text/javascript
AddOutputFilterByType BROTLI_COMPRESS application/javascript
AddOutputFilterByType BROTLI_COMPRESS application/json
AddOutputFilterByType BROTLI_COMPRESS application/xml
AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
</IfModule>
FileETag None
# END RX Theme Cache Headers
HTACCESS;
}
/**
* Add useful note in robots.txt.
*/
public static function robots_txt_cache_note($output, $public) {
$output .= "\n# RX Theme cache headers enabled\n";
return $output;
}
}
RX_Theme_Cache_Headers::init();
endif;
Best functions.php include code
Add this in your RX theme functions.php:
/**
* RX Theme Performance Files
*/
$rx_cache_headers_file = get_template_directory() . '/inc/performance/cache-headers.php';
if (file_exists($rx_cache_headers_file)) {
require_once $rx_cache_headers_file;
}
Important note
This file is safe for dynamic WordPress pages because it avoids full public cache for logged-in users, admin pages, preview pages, cart/checkout pages, POST requests, AJAX, REST write requests, and private-cookie pages.
For the strongest result, combine it with:
Cloudflare Cache Rules
LiteSpeed Cache / Hostinger Cache
Apache .htaccess cache headers
Optimized enqueue.php
preload.php
dns-prefetch/preconnect
Critical CSS
defer/async JavaScript
WebP/AVIF images
This file is a strong base for your RX Theme performance system.