I’ll build this as a full advanced performance/web-vitals.php module for your RX WordPress theme, including Core Web Vitals collection, resource hints, preload helpers, script strategy controls, REST/AJAX reporting, admin-safe toggles, and frontend JS output.
Create this file:
rx-theme/inc/performance/web-vitals.php
Then include it from your functions.php like this:
require_once get_template_directory() . '/inc/performance/web-vitals.php';
This module uses modern WordPress script strategy support such as defer, which WordPress added to wp_enqueue_script() / wp_register_script() arguments, and it also uses WordPress resource hints through wp_resource_hints. The web-vitals package is currently available as version 5.2.0 on npm, and the library supports reporting metrics such as LCP, CLS, INP, FCP and TTFB.
<?php
/**
* RX Theme - Advanced Performance & Core Web Vitals Module
*
* File: inc/performance/web-vitals.php
*
* Features:
* - Core Web Vitals frontend collection
* - LCP, CLS, INP, FCP, TTFB, long task and navigation timing capture
* - REST API endpoint for real user monitoring
* - AJAX fallback endpoint
* - Local database logging with retention control
* - Resource hints: dns-prefetch, preconnect, prefetch, prerender
* - Font preload
* - CSS preload
* - JS preload
* - Hero image preload
* - Fetch priority support
* - Lazy-loading helpers
* - Async/defer script helpers
* - Disable emojis, embeds, dashicons for guests
* - Remove unnecessary WordPress header noise
* - Performance body class
* - Debug mode for admins
* - Safe defaults with filters
*
* Add in functions.php:
* require_once get_template_directory() . '/inc/performance/web-vitals.php';
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'RX_Theme_Web_Vitals' ) ) {
final class RX_Theme_Web_Vitals {
const VERSION = '1.0.0';
const OPTION_KEY = 'rx_theme_web_vitals_settings';
const TABLE_SLUG = 'rx_web_vitals';
const REST_NAMESPACE = 'rx-theme/v1';
const REST_ROUTE = '/web-vitals';
const NONCE_ACTION = 'rx_web_vitals_nonce_action';
const NONCE_NAME = 'rx_web_vitals_nonce';
const TRANSIENT_PREFIX = 'rx_wv_';
private static $instance = null;
private $settings = array();
public static function instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->settings = $this->get_settings();
add_action( 'after_setup_theme', array( $this, 'theme_supports' ), 20 );
add_action( 'init', array( $this, 'maybe_create_table' ) );
add_action( 'init', array( $this, 'register_hooks' ) );
}
public function register_hooks() {
if ( is_admin() && ! wp_doing_ajax() ) {
return;
}
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ), 1 );
add_action( 'wp_head', array( $this, 'print_early_resource_hints' ), 1 );
add_action( 'wp_head', array( $this, 'print_preloads' ), 2 );
add_action( 'wp_head', array( $this, 'print_critical_runtime_config' ), 3 );
add_action( 'wp_footer', array( $this, 'print_web_vitals_collector' ), 99 );
add_filter( 'wp_resource_hints', array( $this, 'resource_hints' ), 10, 2 );
add_filter( 'script_loader_tag', array( $this, 'script_loader_tag' ), 10, 3 );
add_filter( 'style_loader_tag', array( $this, 'style_loader_tag' ), 10, 4 );
add_filter( 'wp_get_attachment_image_attributes', array( $this, 'image_attributes' ), 10, 3 );
add_filter( 'body_class', array( $this, 'body_class' ) );
add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );
add_action( 'wp_ajax_rx_web_vitals', array( $this, 'ajax_receive_web_vitals' ) );
add_action( 'wp_ajax_nopriv_rx_web_vitals', array( $this, 'ajax_receive_web_vitals' ) );
if ( ! empty( $this->settings['cleanup_head'] ) ) {
$this->cleanup_wordpress_head();
}
if ( ! empty( $this->settings['disable_emojis'] ) ) {
$this->disable_emojis();
}
if ( ! empty( $this->settings['disable_embeds'] ) ) {
$this->disable_embeds();
}
if ( ! empty( $this->settings['disable_dashicons_for_guests'] ) ) {
add_action( 'wp_enqueue_scripts', array( $this, 'disable_dashicons_for_guests' ), 100 );
}
}
public function theme_supports() {
add_theme_support( 'html5', array( 'script', 'style' ) );
add_theme_support( 'responsive-embeds' );
add_theme_support( 'align-wide' );
}
public function default_settings() {
return array(
'enabled' => true,
'debug' => false,
'sample_rate' => 1.0,
'storage_enabled' => true,
'storage_retention_days' => 30,
'use_rest' => true,
'use_ajax_fallback' => true,
'cleanup_head' => true,
'disable_emojis' => true,
'disable_embeds' => false,
'disable_dashicons_for_guests' => true,
'defer_theme_scripts' => true,
'async_external_scripts' => false,
'preload_web_vitals_library' => true,
'web_vitals_library_url' => 'https://unpkg.com/web-vitals@5/dist/web-vitals.attribution.iife.js',
'preconnect_urls' => array(
'https://fonts.googleapis.com',
'https://fonts.gstatic.com',
),
'dns_prefetch_urls' => array(
'//fonts.googleapis.com',
'//fonts.gstatic.com',
),
'prefetch_urls' => array(),
'prerender_urls' => array(),
'preload_fonts' => array(),
'preload_styles' => array(),
'preload_scripts' => array(),
'preload_images' => array(),
'critical_css' => '',
'max_payload_bytes' => 12000,
'bot_protection' => true,
'allowed_metrics' => array(
'CLS',
'FCP',
'INP',
'LCP',
'TTFB',
'NavigationTiming',
'LongTask',
'ResourceTiming',
),
);
}
public function get_settings() {
$defaults = $this->default_settings();
$saved = get_option( self::OPTION_KEY, array() );
if ( ! is_array( $saved ) ) {
$saved = array();
}
$settings = wp_parse_args( $saved, $defaults );
/**
* Filter RX Web Vitals settings.
*
* Example:
* add_filter('rx_theme_web_vitals_settings', function($settings) {
* $settings['debug'] = true;
* return $settings;
* });
*/
return apply_filters( 'rx_theme_web_vitals_settings', $settings );
}
public function maybe_create_table() {
if ( empty( $this->settings['storage_enabled'] ) ) {
return;
}
$created = get_option( 'rx_theme_web_vitals_table_created' );
if ( self::VERSION === $created ) {
return;
}
global $wpdb;
$table_name = $this->get_table_name();
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE {$table_name} (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
created_at DATETIME NOT NULL,
metric_name VARCHAR(40) NOT NULL,
metric_value DOUBLE NULL,
metric_rating VARCHAR(20) NULL,
metric_delta DOUBLE NULL,
metric_id VARCHAR(120) NULL,
page_url TEXT NULL,
page_path TEXT NULL,
referrer TEXT NULL,
user_agent TEXT NULL,
connection_type VARCHAR(60) NULL,
navigation_type VARCHAR(80) NULL,
device_memory VARCHAR(30) NULL,
hardware_concurrency VARCHAR(30) NULL,
effective_type VARCHAR(30) NULL,
attribution LONGTEXT NULL,
extra LONGTEXT NULL,
ip_hash VARCHAR(128) NULL,
PRIMARY KEY (id),
KEY metric_name (metric_name),
KEY metric_rating (metric_rating),
KEY created_at (created_at)
) {$charset_collate};";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta( $sql );
update_option( 'rx_theme_web_vitals_table_created', self::VERSION, false );
$this->cleanup_old_rows();
}
private function get_table_name() {
global $wpdb;
return $wpdb->prefix . self::TABLE_SLUG;
}
public function enqueue_assets() {
if ( empty( $this->settings['enabled'] ) ) {
return;
}
if ( $this->is_ignored_request() ) {
return;
}
$library_url = esc_url_raw( $this->settings['web_vitals_library_url'] );
wp_register_script(
'rx-web-vitals-lib',
$library_url,
array(),
null,
array(
'in_footer' => true,
'strategy' => 'defer',
)
);
wp_enqueue_script( 'rx-web-vitals-lib' );
wp_register_script(
'rx-web-vitals-runtime',
'',
array( 'rx-web-vitals-lib' ),
self::VERSION,
array(
'in_footer' => true,
'strategy' => 'defer',
)
);
wp_enqueue_script( 'rx-web-vitals-runtime' );
}
public function print_critical_runtime_config() {
if ( empty( $this->settings['enabled'] ) ) {
return;
}
$config = array(
'restUrl' => esc_url_raw( rest_url( self::REST_NAMESPACE . self::REST_ROUTE ) ),
'ajaxUrl' => esc_url_raw( admin_url( 'admin-ajax.php' ) ),
'nonce' => wp_create_nonce( 'wp_rest' ),
'ajaxNonce' => wp_create_nonce( self::NONCE_ACTION ),
'useRest' => (bool) $this->settings['use_rest'],
'useAjaxFallback' => (bool) $this->settings['use_ajax_fallback'],
'sampleRate' => (float) $this->settings['sample_rate'],
'debug' => (bool) $this->settings['debug'],
'page' => array(
'url' => $this->current_url(),
'path' => wp_parse_url( $this->current_url(), PHP_URL_PATH ),
'isHome' => is_front_page(),
'isSingle' => is_single(),
'isPage' => is_page(),
'isArchive' => is_archive(),
'postId' => get_queried_object_id(),
),
);
echo "\n<script id=\"rx-web-vitals-config\">\n";
echo 'window.RX_WEB_VITALS_CONFIG = ' . wp_json_encode( $config ) . ';';
echo "\n</script>\n";
$critical_css = trim( (string) $this->settings['critical_css'] );
if ( '' !== $critical_css ) {
echo "\n<style id=\"rx-critical-css\">\n";
echo wp_strip_all_tags( $critical_css );
echo "\n</style>\n";
}
}
public function print_web_vitals_collector() {
if ( empty( $this->settings['enabled'] ) ) {
return;
}
if ( $this->is_ignored_request() ) {
return;
}
?>
<script id="rx-web-vitals-collector">
(function () {
'use strict';
var config = window.RX_WEB_VITALS_CONFIG || {};
var sampled = Math.random() <= (Number(config.sampleRate || 1));
if (!sampled) {
return;
}
var queue = [];
var sentIds = {};
var maxQueue = 80;
function log() {
if (config.debug && window.console && console.log) {
console.log.apply(console, arguments);
}
}
function nowISO() {
try {
return new Date().toISOString();
} catch (e) {
return '';
}
}
function safeString(value, max) {
if (typeof value === 'undefined' || value === null) {
return '';
}
value = String(value);
if (value.length > max) {
return value.slice(0, max);
}
return value;
}
function getConnection() {
var c = navigator.connection || navigator.mozConnection || navigator.webkitConnection || {};
return {
effectiveType: safeString(c.effectiveType, 30),
type: safeString(c.type, 60),
downlink: c.downlink || null,
rtt: c.rtt || null,
saveData: !!c.saveData
};
}
function getDevice() {
return {
deviceMemory: navigator.deviceMemory || null,
hardwareConcurrency: navigator.hardwareConcurrency || null,
language: navigator.language || '',
platform: navigator.platform || '',
cookieEnabled: !!navigator.cookieEnabled,
visibilityState: document.visibilityState || ''
};
}
function getNavigationType() {
try {
var nav = performance.getEntriesByType('navigation');
if (nav && nav[0] && nav[0].type) {
return nav[0].type;
}
} catch (e) {}
if (performance && performance.navigation) {
var map = {
0: 'navigate',
1: 'reload',
2: 'back_forward',
255: 'reserved'
};
return map[performance.navigation.type] || 'unknown';
}
return 'unknown';
}
function cleanAttribution(attribution) {
if (!attribution || typeof attribution !== 'object') {
return {};
}
var clean = {};
var allowed = [
'element',
'eventType',
'eventTarget',
'loadState',
'url',
'largestShiftTarget',
'largestShiftTime',
'largestShiftValue',
'largestShiftSource',
'largestShiftEntry',
'lcpEntry',
'lcpResourceEntry',
'lcpResourceLoadDelay',
'lcpResourceLoadDuration',
'lcpElementRenderDelay',
'lcpElement',
'timeToFirstByte',
'resourceLoadDelay',
'resourceLoadDuration',
'elementRenderDelay',
'interactionTarget',
'interactionType',
'interactionTime',
'inputDelay',
'processingDuration',
'presentationDelay',
'nextPaintTime'
];
allowed.forEach(function (key) {
if (Object.prototype.hasOwnProperty.call(attribution, key)) {
var value = attribution[key];
if (value && typeof value === 'object') {
try {
value = JSON.stringify(value);
} catch (e) {
value = String(value);
}
}
clean[key] = safeString(value, 1000);
}
});
return clean;
}
function buildPayload(metric, extra) {
var connection = getConnection();
var device = getDevice();
return {
createdAt: nowISO(),
name: safeString(metric.name || extra.name || '', 40),
value: Number(metric.value || extra.value || 0),
rating: safeString(metric.rating || extra.rating || '', 20),
delta: Number(metric.delta || 0),
id: safeString(metric.id || '', 120),
navigationType: safeString(metric.navigationType || getNavigationType(), 80),
pageUrl: safeString((config.page && config.page.url) || location.href, 2000),
pagePath: safeString((config.page && config.page.path) || location.pathname, 1000),
referrer: safeString(document.referrer || '', 2000),
userAgent: safeString(navigator.userAgent || '', 600),
connectionType: connection.type,
effectiveType: connection.effectiveType,
deviceMemory: safeString(device.deviceMemory, 30),
hardwareConcurrency: safeString(device.hardwareConcurrency, 30),
attribution: cleanAttribution(metric.attribution || {}),
extra: extra || {}
};
}
function sendBeaconPayload(payload) {
var body = JSON.stringify(payload);
if (navigator.sendBeacon && config.restUrl && config.useRest) {
try {
var blob = new Blob([body], { type: 'application/json' });
if (navigator.sendBeacon(config.restUrl, blob)) {
return true;
}
} catch (e) {}
}
return false;
}
function sendFetchPayload(payload) {
if (!config.restUrl || !config.useRest || !window.fetch) {
return Promise.reject();
}
return fetch(config.restUrl, {
method: 'POST',
credentials: 'same-origin',
keepalive: true,
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': config.nonce || ''
},
body: JSON.stringify(payload)
});
}
function sendAjaxPayload(payload) {
if (!config.ajaxUrl || !config.useAjaxFallback || !window.fetch) {
return Promise.reject();
}
var form = new FormData();
form.append('action', 'rx_web_vitals');
form.append('nonce', config.ajaxNonce || '');
form.append('payload', JSON.stringify(payload));
return fetch(config.ajaxUrl, {
method: 'POST',
credentials: 'same-origin',
keepalive: true,
body: form
});
}
function flush(payload) {
if (!payload || !payload.name) {
return;
}
var dedupeKey = payload.name + ':' + payload.id + ':' + payload.value;
if (sentIds[dedupeKey]) {
return;
}
sentIds[dedupeKey] = true;
log('[RX Web Vitals]', payload.name, payload.value, payload.rating, payload);
if (sendBeaconPayload(payload)) {
return;
}
sendFetchPayload(payload).catch(function () {
return sendAjaxPayload(payload);
}).catch(function () {
queue.push(payload);
if (queue.length > maxQueue) {
queue.shift();
}
});
}
function report(metric, extra) {
flush(buildPayload(metric || {}, extra || {}));
}
function observeLongTasks() {
if (!('PerformanceObserver' in window)) {
return;
}
try {
var observer = new PerformanceObserver(function (list) {
list.getEntries().forEach(function (entry) {
if (entry.duration >= 50) {
report({
name: 'LongTask',
value: entry.duration,
rating: entry.duration > 200 ? 'poor' : 'needs-improvement',
id: 'longtask-' + Math.round(entry.startTime)
}, {
name: 'LongTask',
startTime: entry.startTime,
duration: entry.duration,
entryType: entry.entryType
});
}
});
});
observer.observe({ type: 'longtask', buffered: true });
} catch (e) {}
}
function reportNavigationTiming() {
try {
var nav = performance.getEntriesByType('navigation');
if (!nav || !nav[0]) {
return;
}
var n = nav[0];
var metrics = {
dns: n.domainLookupEnd - n.domainLookupStart,
connect: n.connectEnd - n.connectStart,
tls: n.secureConnectionStart > 0 ? n.connectEnd - n.secureConnectionStart : 0,
request: n.responseStart - n.requestStart,
response: n.responseEnd - n.responseStart,
domInteractive: n.domInteractive,
domContentLoaded: n.domContentLoadedEventEnd - n.domContentLoadedEventStart,
loadEvent: n.loadEventEnd - n.loadEventStart,
transferSize: n.transferSize || 0,
encodedBodySize: n.encodedBodySize || 0,
decodedBodySize: n.decodedBodySize || 0,
type: n.type || ''
};
report({
name: 'NavigationTiming',
value: n.loadEventEnd || n.duration || 0,
rating: 'info',
id: 'navigation-' + Date.now()
}, metrics);
} catch (e) {}
}
function reportResourceTiming() {
try {
var resources = performance.getEntriesByType('resource') || [];
var slow = resources
.filter(function (r) {
return r.duration >= 500;
})
.slice(0, 10)
.map(function (r) {
return {
name: safeString(r.name, 300),
initiatorType: safeString(r.initiatorType, 40),
duration: Math.round(r.duration),
transferSize: r.transferSize || 0,
encodedBodySize: r.encodedBodySize || 0,
decodedBodySize: r.decodedBodySize || 0
};
});
if (slow.length) {
report({
name: 'ResourceTiming',
value: slow.length,
rating: 'info',
id: 'resource-' + Date.now()
}, {
slowResources: slow
});
}
} catch (e) {}
}
function initWebVitals() {
var wv = window.webVitals;
if (!wv) {
log('[RX Web Vitals] webVitals library not found');
return;
}
var options = {
reportAllChanges: true
};
if (typeof wv.onCLS === 'function') {
wv.onCLS(report, options);
}
if (typeof wv.onFCP === 'function') {
wv.onFCP(report, options);
}
if (typeof wv.onINP === 'function') {
wv.onINP(report, options);
}
if (typeof wv.onLCP === 'function') {
wv.onLCP(report, options);
}
if (typeof wv.onTTFB === 'function') {
wv.onTTFB(report, options);
}
observeLongTasks();
window.addEventListener('load', function () {
setTimeout(reportNavigationTiming, 0);
setTimeout(reportResourceTiming, 1500);
});
}
function retryInit(count) {
count = count || 0;
if (window.webVitals) {
initWebVitals();
return;
}
if (count < 30) {
setTimeout(function () {
retryInit(count + 1);
}, 100);
}
}
retryInit(0);
window.addEventListener('online', function () {
var copy = queue.slice();
queue = [];
copy.forEach(flush);
});
document.addEventListener('visibilitychange', function () {
if (document.visibilityState === 'hidden' && queue.length) {
var copy = queue.slice();
queue = [];
copy.forEach(function (payload) {
sendBeaconPayload(payload);
});
}
});
})();
</script>
<?php
}
public function register_rest_routes() {
register_rest_route(
self::REST_NAMESPACE,
self::REST_ROUTE,
array(
'methods' => 'POST',
'callback' => array( $this, 'rest_receive_web_vitals' ),
'permission_callback' => '__return_true',
'args' => array(),
)
);
}
public function rest_receive_web_vitals( WP_REST_Request $request ) {
if ( empty( $this->settings['enabled'] ) ) {
return new WP_REST_Response(
array(
'success' => false,
'message' => 'disabled',
),
403
);
}
if ( $this->is_bot_request() ) {
return new WP_REST_Response(
array(
'success' => false,
'message' => 'ignored',
),
202
);
}
$raw = $request->get_body();
if ( strlen( $raw ) > absint( $this->settings['max_payload_bytes'] ) ) {
return new WP_REST_Response(
array(
'success' => false,
'message' => 'payload-too-large',
),
413
);
}
$data = json_decode( $raw, true );
if ( ! is_array( $data ) ) {
$data = $request->get_json_params();
}
$result = $this->handle_metric_payload( $data );
return new WP_REST_Response( $result, ! empty( $result['success'] ) ? 200 : 400 );
}
public function ajax_receive_web_vitals() {
if ( empty( $this->settings['enabled'] ) ) {
wp_send_json_error( array( 'message' => 'disabled' ), 403 );
}
check_ajax_referer( self::NONCE_ACTION, 'nonce' );
$payload = isset( $_POST['payload'] ) ? wp_unslash( $_POST['payload'] ) : '';
if ( strlen( $payload ) > absint( $this->settings['max_payload_bytes'] ) ) {
wp_send_json_error( array( 'message' => 'payload-too-large' ), 413 );
}
$data = json_decode( $payload, true );
$result = $this->handle_metric_payload( $data );
if ( ! empty( $result['success'] ) ) {
wp_send_json_success( $result );
}
wp_send_json_error( $result, 400 );
}
private function handle_metric_payload( $data ) {
if ( ! is_array( $data ) ) {
return array(
'success' => false,
'message' => 'invalid-payload',
);
}
$metric_name = isset( $data['name'] ) ? sanitize_key( $data['name'] ) : '';
if ( '' === $metric_name ) {
return array(
'success' => false,
'message' => 'missing-metric',
);
}
$allowed = array_map( 'sanitize_key', (array) $this->settings['allowed_metrics'] );
if ( ! in_array( $metric_name, $allowed, true ) ) {
return array(
'success' => false,
'message' => 'metric-not-allowed',
);
}
$value = isset( $data['value'] ) ? (float) $data['value'] : 0;
if ( $value < 0 ) {
$value = 0;
}
$clean = array(
'created_at' => current_time( 'mysql', true ),
'metric_name' => $metric_name,
'metric_value' => $value,
'metric_rating' => isset( $data['rating'] ) ? sanitize_text_field( $data['rating'] ) : '',
'metric_delta' => isset( $data['delta'] ) ? (float) $data['delta'] : 0,
'metric_id' => isset( $data['id'] ) ? sanitize_text_field( $data['id'] ) : '',
'page_url' => isset( $data['pageUrl'] ) ? esc_url_raw( $data['pageUrl'] ) : '',
'page_path' => isset( $data['pagePath'] ) ? sanitize_text_field( $data['pagePath'] ) : '',
'referrer' => isset( $data['referrer'] ) ? esc_url_raw( $data['referrer'] ) : '',
'user_agent' => isset( $data['userAgent'] ) ? sanitize_text_field( $data['userAgent'] ) : '',
'connection_type' => isset( $data['connectionType'] ) ? sanitize_text_field( $data['connectionType'] ) : '',
'navigation_type' => isset( $data['navigationType'] ) ? sanitize_text_field( $data['navigationType'] ) : '',
'device_memory' => isset( $data['deviceMemory'] ) ? sanitize_text_field( $data['deviceMemory'] ) : '',
'hardware_concurrency' => isset( $data['hardwareConcurrency'] ) ? sanitize_text_field( $data['hardwareConcurrency'] ) : '',
'effective_type' => isset( $data['effectiveType'] ) ? sanitize_text_field( $data['effectiveType'] ) : '',
'attribution' => isset( $data['attribution'] ) ? wp_json_encode( $this->recursive_sanitize( $data['attribution'] ) ) : '',
'extra' => isset( $data['extra'] ) ? wp_json_encode( $this->recursive_sanitize( $data['extra'] ) ) : '',
'ip_hash' => $this->get_ip_hash(),
);
if ( ! empty( $this->settings['storage_enabled'] ) ) {
$this->insert_metric( $clean );
}
do_action( 'rx_theme_web_vitals_metric_received', $clean, $data );
return array(
'success' => true,
'message' => 'stored',
);
}
private function insert_metric( $data ) {
global $wpdb;
$table_name = $this->get_table_name();
$wpdb->insert(
$table_name,
$data,
array(
'%s',
'%s',
'%f',
'%s',
'%f',
'%s',
'%s',
'%s',
'%s',
'%s',
'%s',
'%s',
'%s',
'%s',
'%s',
'%s',
'%s',
)
);
if ( mt_rand( 1, 100 ) === 1 ) {
$this->cleanup_old_rows();
}
}
private function cleanup_old_rows() {
if ( empty( $this->settings['storage_enabled'] ) ) {
return;
}
$days = absint( $this->settings['storage_retention_days'] );
if ( $days < 1 ) {
$days = 30;
}
global $wpdb;
$table_name = $this->get_table_name();
$date = gmdate( 'Y-m-d H:i:s', time() - ( DAY_IN_SECONDS * $days ) );
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$table_name} WHERE created_at < %s",
$date
)
);
}
private function recursive_sanitize( $value ) {
if ( is_array( $value ) ) {
$clean = array();
foreach ( $value as $key => $item ) {
$clean_key = is_string( $key ) ? sanitize_key( $key ) : absint( $key );
$clean[ $clean_key ] = $this->recursive_sanitize( $item );
}
return $clean;
}
if ( is_bool( $value ) ) {
return $value;
}
if ( is_numeric( $value ) ) {
return $value + 0;
}
return sanitize_text_field( (string) $value );
}
public function resource_hints( $urls, $relation_type ) {
if ( empty( $this->settings['enabled'] ) ) {
return $urls;
}
$map = array(
'dns-prefetch' => 'dns_prefetch_urls',
'preconnect' => 'preconnect_urls',
'prefetch' => 'prefetch_urls',
'prerender' => 'prerender_urls',
);
if ( empty( $map[ $relation_type ] ) ) {
return $urls;
}
$key = $map[ $relation_type ];
foreach ( (array) $this->settings[ $key ] as $url ) {
$url = trim( (string) $url );
if ( '' === $url ) {
continue;
}
if ( 'preconnect' === $relation_type ) {
$urls[] = array(
'href' => esc_url( $url ),
'crossorigin' => 'anonymous',
);
} else {
$urls[] = esc_url( $url );
}
}
return array_unique( $urls, SORT_REGULAR );
}
public function print_early_resource_hints() {
if ( empty( $this->settings['enabled'] ) ) {
return;
}
if ( ! empty( $this->settings['preload_web_vitals_library'] ) && ! empty( $this->settings['web_vitals_library_url'] ) ) {
printf(
'<link rel="preload" href="%s" as="script" crossorigin="anonymous">' . "\n",
esc_url( $this->settings['web_vitals_library_url'] )
);
}
}
public function print_preloads() {
if ( empty( $this->settings['enabled'] ) ) {
return;
}
foreach ( (array) $this->settings['preload_fonts'] as $font_url ) {
$font_url = esc_url( $font_url );
if ( $font_url ) {
printf(
'<link rel="preload" href="%s" as="font" type="%s" crossorigin="anonymous">' . "\n",
$font_url,
esc_attr( $this->guess_font_mime_type( $font_url ) )
);
}
}
foreach ( (array) $this->settings['preload_styles'] as $style_url ) {
$style_url = esc_url( $style_url );
if ( $style_url ) {
printf(
'<link rel="preload" href="%s" as="style">' . "\n",
$style_url
);
}
}
foreach ( (array) $this->settings['preload_scripts'] as $script_url ) {
$script_url = esc_url( $script_url );
if ( $script_url ) {
printf(
'<link rel="preload" href="%s" as="script" crossorigin="anonymous">' . "\n",
$script_url
);
}
}
foreach ( (array) $this->settings['preload_images'] as $image_url ) {
$image_url = esc_url( $image_url );
if ( $image_url ) {
printf(
'<link rel="preload" href="%s" as="image" fetchpriority="high">' . "\n",
$image_url
);
}
}
}
private function guess_font_mime_type( $url ) {
$path = wp_parse_url( $url, PHP_URL_PATH );
$ext = strtolower( pathinfo( (string) $path, PATHINFO_EXTENSION ) );
switch ( $ext ) {
case 'woff2':
return 'font/woff2';
case 'woff':
return 'font/woff';
case 'ttf':
return 'font/ttf';
case 'otf':
return 'font/otf';
default:
return 'font/woff2';
}
}
public function script_loader_tag( $tag, $handle, $src ) {
if ( is_admin() ) {
return $tag;
}
$defer_handles = apply_filters(
'rx_theme_defer_script_handles',
array(
'rx-web-vitals-lib',
'rx-web-vitals-runtime',
)
);
$async_handles = apply_filters(
'rx_theme_async_script_handles',
array()
);
if ( in_array( $handle, $defer_handles, true ) && false === strpos( $tag, ' defer' ) ) {
$tag = str_replace( '<script ', '<script defer ', $tag );
}
if ( in_array( $handle, $async_handles, true ) && false === strpos( $tag, ' async' ) ) {
$tag = str_replace( '<script ', '<script async ', $tag );
}
if ( false !== strpos( $src, 'unpkg.com' ) || false !== strpos( $src, 'cdn.jsdelivr.net' ) ) {
if ( false === strpos( $tag, ' crossorigin=' ) ) {
$tag = str_replace( '<script ', '<script crossorigin="anonymous" ', $tag );
}
}
return $tag;
}
public function style_loader_tag( $html, $handle, $href, $media ) {
$preload_handles = apply_filters( 'rx_theme_preload_style_handles', array() );
if ( in_array( $handle, $preload_handles, true ) ) {
$html = sprintf(
'<link rel="preload" href="%1$s" as="style" onload="this.onload=null;this.rel=\'stylesheet\'">%2$s<noscript><link rel="stylesheet" href="%1$s"></noscript>',
esc_url( $href ),
"\n"
);
}
return $html;
}
public function image_attributes( $attr, $attachment, $size ) {
if ( is_admin() ) {
return $attr;
}
if ( empty( $attr['loading'] ) ) {
$attr['loading'] = 'lazy';
}
if ( empty( $attr['decoding'] ) ) {
$attr['decoding'] = 'async';
}
if ( is_singular() && in_the_loop() && is_main_query() ) {
static $first_content_image = false;
if ( false === $first_content_image ) {
$first_content_image = true;
$attr['loading'] = 'eager';
$attr['fetchpriority'] = 'high';
}
}
return $attr;
}
public function body_class( $classes ) {
$classes[] = 'rx-performance-enabled';
if ( ! empty( $this->settings['debug'] ) ) {
$classes[] = 'rx-performance-debug';
}
return $classes;
}
private function cleanup_wordpress_head() {
remove_action( 'wp_head', 'wp_generator' );
remove_action( 'wp_head', 'wlwmanifest_link' );
remove_action( 'wp_head', 'rsd_link' );
remove_action( 'wp_head', 'wp_shortlink_wp_head' );
remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head' );
remove_action( 'wp_head', 'rest_output_link_wp_head' );
remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
remove_action( 'template_redirect', 'rest_output_link_header', 11 );
}
private function disable_emojis() {
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
add_filter( 'emoji_svg_url', '__return_false' );
}
private function disable_embeds() {
wp_deregister_script( 'wp-embed' );
}
public function disable_dashicons_for_guests() {
if ( ! is_user_logged_in() ) {
wp_dequeue_style( 'dashicons' );
wp_deregister_style( 'dashicons' );
}
}
private function current_url() {
$scheme = is_ssl() ? 'https://' : 'http://';
$host = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '';
$uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
return esc_url_raw( $scheme . $host . $uri );
}
private function get_ip_hash() {
$ip = '';
if ( ! empty( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
$ip = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_CONNECTING_IP'] ) );
} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
$parts = explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) );
$ip = trim( $parts[0] );
} elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) {
$ip = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
}
if ( '' === $ip ) {
return '';
}
return hash_hmac( 'sha256', $ip, wp_salt( 'auth' ) );
}
private function is_bot_request() {
if ( empty( $this->settings['bot_protection'] ) ) {
return false;
}
$user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? strtolower( sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) ) : '';
if ( '' === $user_agent ) {
return true;
}
$bots = array(
'bot',
'crawl',
'spider',
'slurp',
'mediapartners',
'facebookexternalhit',
'whatsapp',
'telegrambot',
'linkedinbot',
'pingdom',
'lighthouse',
'pagespeed',
'gtmetrix',
'uptimerobot',
);
foreach ( $bots as $bot ) {
if ( false !== strpos( $user_agent, $bot ) ) {
return true;
}
}
return false;
}
private function is_ignored_request() {
if ( is_feed() || is_robots() || is_trackback() || wp_doing_cron() ) {
return true;
}
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
return true;
}
return false;
}
public static function get_recent_metrics( $limit = 100 ) {
global $wpdb;
$instance = self::instance();
$table = $instance->get_table_name();
$limit = absint( $limit );
if ( $limit < 1 ) {
$limit = 100;
}
return $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$table} ORDER BY created_at DESC LIMIT %d",
$limit
),
ARRAY_A
);
}
public static function get_metric_summary( $days = 7 ) {
global $wpdb;
$instance = self::instance();
$table = $instance->get_table_name();
$days = absint( $days );
if ( $days < 1 ) {
$days = 7;
}
$since = gmdate( 'Y-m-d H:i:s', time() - ( DAY_IN_SECONDS * $days ) );
return $wpdb->get_results(
$wpdb->prepare(
"SELECT
metric_name,
metric_rating,
COUNT(*) as total,
AVG(metric_value) as avg_value,
MIN(metric_value) as min_value,
MAX(metric_value) as max_value
FROM {$table}
WHERE created_at >= %s
GROUP BY metric_name, metric_rating
ORDER BY metric_name ASC, total DESC",
$since
),
ARRAY_A
);
}
}
RX_Theme_Web_Vitals::instance();
}
/**
* Helper: add preconnect URL.
*/
if ( ! function_exists( 'rx_theme_add_preconnect' ) ) {
function rx_theme_add_preconnect( $url ) {
add_filter(
'rx_theme_web_vitals_settings',
function ( $settings ) use ( $url ) {
$settings['preconnect_urls'][] = esc_url_raw( $url );
return $settings;
}
);
}
}
/**
* Helper: add dns-prefetch URL.
*/
if ( ! function_exists( 'rx_theme_add_dns_prefetch' ) ) {
function rx_theme_add_dns_prefetch( $url ) {
add_filter(
'rx_theme_web_vitals_settings',
function ( $settings ) use ( $url ) {
$settings['dns_prefetch_urls'][] = esc_url_raw( $url );
return $settings;
}
);
}
}
/**
* Helper: preload font.
*/
if ( ! function_exists( 'rx_theme_preload_font' ) ) {
function rx_theme_preload_font( $url ) {
add_filter(
'rx_theme_web_vitals_settings',
function ( $settings ) use ( $url ) {
$settings['preload_fonts'][] = esc_url_raw( $url );
return $settings;
}
);
}
}
/**
* Helper: preload image.
*/
if ( ! function_exists( 'rx_theme_preload_image' ) ) {
function rx_theme_preload_image( $url ) {
add_filter(
'rx_theme_web_vitals_settings',
function ( $settings ) use ( $url ) {
$settings['preload_images'][] = esc_url_raw( $url );
return $settings;
}
);
}
}
/**
* Helper: preload script.
*/
if ( ! function_exists( 'rx_theme_preload_script' ) ) {
function rx_theme_preload_script( $url ) {
add_filter(
'rx_theme_web_vitals_settings',
function ( $settings ) use ( $url ) {
$settings['preload_scripts'][] = esc_url_raw( $url );
return $settings;
}
);
}
}
/**
* Helper: preload style.
*/
if ( ! function_exists( 'rx_theme_preload_style' ) ) {
function rx_theme_preload_style( $url ) {
add_filter(
'rx_theme_web_vitals_settings',
function ( $settings ) use ( $url ) {
$settings['preload_styles'][] = esc_url_raw( $url );
return $settings;
}
);
}
}
/**
* Helper: get RX Web Vitals summary.
*/
if ( ! function_exists( 'rx_theme_get_web_vitals_summary' ) ) {
function rx_theme_get_web_vitals_summary( $days = 7 ) {
if ( ! class_exists( 'RX_Theme_Web_Vitals' ) ) {
return array();
}
return RX_Theme_Web_Vitals::get_metric_summary( $days );
}
}
For your functions.php, add this line only once:
require_once get_template_directory() . '/inc/performance/web-vitals.php';
Optional custom settings example:
add_filter( 'rx_theme_web_vitals_settings', function ( $settings ) {
$settings['debug'] = false;
$settings['sample_rate'] = 1.0;
$settings['preconnect_urls'][] = 'https://static-assets-cdnrx.rxharun.com';
$settings['dns_prefetch_urls'][] = '//static-assets-cdnrx.rxharun.com';
$settings['preload_images'][] = 'https://rxharun.com/wp-content/uploads/hero.webp';
return $settings;
} );
Important: after adding this file, clear all cache from WordPress cache plugin, Cloudflare/CDN, browser cache, then test in Chrome DevTools, PageSpeed Insights, and your database table: wp_rx_web_vitals.