false, 'fragments' => 'default', 'emoji' => false, 'embeds' => false, 'heartbeat' => false, 'rules' => array()); } public static function settings() { return array_merge(self::defaults(), (array) get_option(self::OPTION, array())); } public static function disabled() { return defined('SLX_PERF_DISABLE') && SLX_PERF_DISABLE; } public static function text_param($source, $key) { return isset($source[$key]) && is_scalar($source[$key]) ? sanitize_text_field(wp_unslash((string) $source[$key])) : ''; } public static function current_path() { $path = wp_parse_url(isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '/', PHP_URL_PATH); return is_string($path) ? $path : '/'; } public static function safe_url($url) { $p = wp_parse_url($url); if (!is_array($p)) { return ''; } // Never retain tokens, credentials, search terms or URL fragments. return (isset($p['host']) ? (isset($p['scheme']) ? $p['scheme'] : 'https') . '://' . $p['host'] . (isset($p['port']) ? ':' . (int) $p['port'] : '') : '') . (isset($p['path']) ? $p['path'] : ''); } private static $source_roots = null; // Physical locations and URLs are resolved locally, never stored in reports. public static function source_roots() { if (self::$source_roots !== null) { return self::$source_roots; } self::$source_roots = array(); $roots = array(array('path'=>WP_PLUGIN_DIR, 'url'=>plugins_url('/'), 'prefix'=>'plugins/', 'kind'=>'plugin')); if (defined('WPMU_PLUGIN_DIR') && defined('WPMU_PLUGIN_URL')) { $roots[] = array('path'=>WPMU_PLUGIN_DIR, 'url'=>WPMU_PLUGIN_URL . '/', 'prefix'=>'mu-plugins/', 'kind'=>'mu'); } // WordPress registers real paths for symlinked plugin directories. global $wp_plugin_paths; foreach ((array) $wp_plugin_paths as $logical => $physical) { $relative = self::relative_source_path($logical, WP_PLUGIN_DIR); if ($relative !== false) { $roots[] = array('path'=>$physical, 'url'=>plugins_url($relative . '/'), 'prefix'=>'plugins/' . $relative . '/', 'kind'=>'plugin'); } } foreach (wp_get_themes() as $slug => $theme) { $roots[] = array('path'=>$theme->get_stylesheet_directory(), 'url'=>$theme->get_stylesheet_directory_uri() . '/', 'prefix'=>'themes/' . $slug . '/', 'kind'=>'theme', 'theme'=>$slug); } foreach ($roots as $root) { $real = realpath($root['path']); if (!$real) { continue; } $root['path'] = wp_normalize_path($real); $root['url'] = trailingslashit($root['url']); self::$source_roots[] = $root; } usort(self::$source_roots, function($a, $b) { return strlen($b['path']) - strlen($a['path']); }); return self::$source_roots; } public static function relative_source_path($file, $root) { $file = wp_normalize_path($file); $root = trailingslashit(wp_normalize_path($root)); return strpos($file, $root) === 0 ? substr($file, strlen($root)) : false; } private static function valid_source_relative($relative) { return is_string($relative) && $relative !== '' && !preg_match('~(^/|\\\\|:|[\x00-\x1F]|(?:^|/)\.{1,2}(?:/|$))~', $relative); } public static function source_reference($file) { $real = realpath($file); if (!$real) { return ''; } foreach (self::source_roots() as $root) { $relative = self::relative_source_path($real, $root['path']); if ($relative !== false && self::valid_source_relative($relative)) { return $root['prefix'] . $relative; } } return ''; } public static function resolve_source($reference, $is_url = false) { if (!is_string($reference)) { return ''; } foreach (self::source_roots() as $root) { $prefix = $is_url ? $root['url'] : $root['prefix']; if (strpos($reference, $prefix) !== 0) { continue; } $relative = substr($reference, strlen($prefix)); if ($is_url) { $relative = rawurldecode($relative); } if (!self::valid_source_relative($relative)) { continue; } $real = realpath($root['path'] . '/' . $relative); // Reject traversal and links escaping this configured root. if ($real && self::relative_source_path($real, $root['path']) !== false) { return $real; } } return ''; } public static function owner($path) { $path = (string) $path; $is_url = (bool) preg_match('~^https?://~i', $path); $reference = $is_url ? self::source_reference(self::resolve_source(self::safe_url($path), true)) : self::source_reference($path); foreach (array('plugins'=>'Plugin', 'mu-plugins'=>'MU plugin', 'themes'=>'Theme') as $folder=>$label) { if (strpos($reference, $folder . '/') === 0) { return $label . ': ' . explode('/', substr($reference, strlen($folder) + 1))[0]; } } if (strpos($path, '/wp-includes/') !== false || strpos($path, '/wp-admin/') !== false) { return 'WordPress core'; } return 'Unknown / external'; } public static function start() { if (self::disabled() || is_admin() || wp_doing_ajax() || wp_doing_cron() || (defined('REST_REQUEST') && REST_REQUEST)) { return; } if (!current_user_can('manage_options') || !wp_verify_nonce(self::text_param($_GET, '_slxp'), 'slxp_profile')) { return; } $mode = self::text_param($_GET, 'slxp_profile'); if (!in_array($mode, array('baseline', 'trial'), true)) { return; } self::source_roots(); global $wpdb; self::$profile = true; self::$baseline = $mode === 'baseline'; self::$uid = get_current_user_id(); self::$id = wp_generate_uuid4(); self::$start = microtime(true); self::$query_start = count((array) $wpdb->queries); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- Established cache-plugin flag; its external API name cannot be prefixed. if (!defined('DONOTCACHEPAGE')) { define('DONOTCACHEPAGE', true); } // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- Established cache/minification flag; its external API name cannot be prefixed. if (!defined('DONOTMINIFY')) { define('DONOTMINIFY', true); } // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- WordPress core query-profiling flag; its API name cannot be prefixed. if (!defined('SAVEQUERIES')) { define('SAVEQUERIES', true); } add_action('send_headers', function() { nocache_headers(); header('Referrer-Policy: same-origin'); header('X-Robots-Tag: noindex, nofollow', true); }); add_action('elementor/frontend/before_render', array(__CLASS__, 'element_start'), -999); add_action('elementor/frontend/after_render', array(__CLASS__, 'element_end'), 999); add_filter('log_query_custom_data', array(__CLASS__, 'query_context'), 10, 5); add_filter('http_request_args', array(__CLASS__, 'http_start'), 999, 2); add_action('http_api_debug', array(__CLASS__, 'http_end'), 10, 5); add_action('shutdown', array(__CLASS__, 'finish'), PHP_INT_MAX); add_action('wp_enqueue_scripts', function() { wp_enqueue_script('slxp-top-fixes', plugins_url('assets/top-fixes.js', __FILE__), array(), self::VERSION, true); wp_enqueue_script('slxp-inspector', plugins_url('assets/inspector.js', __FILE__), array('slxp-top-fixes'), self::VERSION, true); }, 1); } public static function element_start($element) { self::$elements[] = array('id' => sanitize_key($element->get_id()), 'name' => sanitize_key($element->get_name())); } public static function element_end($element) { // Unwind to the matching element, including nested render contexts. for ($i = count(self::$elements) - 1; $i >= 0; $i--) { if (self::$elements[$i]['id'] === sanitize_key($element->get_id())) { self::$elements = array_slice(self::$elements, 0, $i); break; } } } public static function query_context($data, $query, $elapsed, $stack, $started) { $frames = array(); // Capture bounded caller metadata for this authenticated diagnostic; arguments are excluded. // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace -- Required for query attribution, not debug logging. foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 28) as $frame) { if (empty($frame['file']) || strpos($frame['file'], __DIR__) === 0) { continue; } $owner = self::owner($frame['file']); if (strpos($owner, 'Plugin:') === 0 || strpos($owner, 'Theme:') === 0 || strpos($owner, 'MU plugin:') === 0) { $frames[] = array('file' => self::source_reference($frame['file']), 'line' => isset($frame['line']) ? (int) $frame['line'] : 0, 'owner' => $owner); if (count($frames) >= 5) { break; } } } $data['slxp'] = $frames; $data['slxp_elements'] = array_slice(self::$elements, -8); return $data; } public static function http_start($args, $url) { $key = hash('sha256', $url); self::$http_starts[$key][] = microtime(true); return $args; } public static function http_end($response, $context, $class, $args, $url) { if ($context !== 'response' || count(self::$http) >= 100) { return; } $key = hash('sha256', $url); $t = !empty(self::$http_starts[$key]) ? array_pop(self::$http_starts[$key]) : null; self::$http[] = array('url' => self::safe_url($url), 'ms' => $t ? round((microtime(true) - $t) * 1000, 2) : null, 'status' => is_wp_error($response) ? 'error' : wp_remote_retrieve_response_code($response)); } public static function effective() { if (self::disabled() || self::$baseline || is_admin() || wp_doing_ajax() || wp_doing_cron() || (defined('REST_REQUEST') && REST_REQUEST)) { return false; } return self::$profile || !empty(self::settings()['live']); } public static function protected_route() { if ((function_exists('is_cart') && is_cart()) || (function_exists('is_checkout') && is_checkout()) || (function_exists('is_account_page') && is_account_page())) { return true; } foreach (array('wc-ajax', 'wc-api', 'add-to-cart', 'rest_route', 'pay_for_order', 'key') as $key) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only route guard; presence only disables optimization. if (isset($_GET[$key])) { return true; } } return false; } public static function features() { if (!self::effective() || self::protected_route()) { return; } $s = self::settings(); if ($s['emoji']) { remove_action('wp_head', 'print_emoji_detection_script', 7); remove_action('wp_print_styles', 'print_emoji_styles'); remove_action('wp_enqueue_scripts', 'wp_enqueue_emoji_styles'); } } public static function fragments($data, $handle) { if ($handle !== 'wc-cart-fragments' || !self::effective() || self::protected_route()) { return $data; } $mode = self::settings()['fragments']; $shop = function_exists('is_woocommerce') && is_woocommerce(); if ($mode === 'off' || ($mode === 'shop' && !$shop)) { return null; } return $data; } public static function protected_handle($handle) { return (bool) preg_match('/^(slxp-|jquery(?:$|-)|wp-(?:hooks|i18n|api-fetch|data|element|polyfill)|wc-(?:cart|checkout|add-to-cart|country|address|credit|password|settings|blocks)|woocommerce$|js-cookie$)/', $handle) || (bool) preg_match('/paypal|ppcp|stripe|sagepay|elavon|payment|recaptcha|captcha|cookieyes|cookie-law|consent|wordfence/i', $handle); } public static function dependency_closure($registry, $roots) { $out = array(); $visit = function($h) use (&$visit, &$out, $registry) { if (isset($out[$h])) { return; } $out[$h] = true; if (isset($registry->registered[$h])) { foreach ((array) $registry->registered[$h]->deps as $dep) { $visit($dep); } } }; foreach ($roots as $h) { $visit($h); } return array_keys($out); } public static function filter_assets() { if (!self::$profile && !self::effective()) { return; } global $wp_scripts, $wp_styles; $s = self::settings(); foreach (array('js' => $wp_scripts, 'css' => $wp_styles) as $kind => $registry) { if (!is_object($registry)) { continue; } $roots = array_unique(array_merge((array) $registry->queue, (array) $registry->done)); $active = self::dependency_closure($registry, $roots); foreach ($active as $h) { if (!isset($registry->registered[$h])) { continue; } $a = $registry->registered[$h]; $src = (string) $a->src; if ($src && strpos($src, '//') === false) { $src = rtrim($registry->base_url, '/') . '/' . ltrim($src, '/'); } $key = $kind . ':' . $h; if (self::$profile) { self::$assets[$key] = array('kind' => $kind, 'handle' => $h, 'url' => self::safe_url($src), 'owner' => self::owner($src), 'deps' => $a->deps, 'protected' => self::protected_handle($h), 'state' => 'enqueued'); } $wanted = false; foreach ($s['rules'] as $r) { if ($r['kind'] === $kind && $r['handle'] === $h && $r['path'] === self::current_path()) { $wanted = true; } } if ($kind === 'js' && (($h === 'wp-embed' && $s['embeds']) || ($h === 'heartbeat' && $s['heartbeat']))) { $wanted = true; } if (!$wanted || !self::effective()) { continue; } $reason = ''; if (self::protected_route()) { $reason = 'Protected cart / checkout / account / transaction route'; } elseif (self::protected_handle($h)) { $reason = 'Protected core, commerce, payment or consent handle'; } elseif (in_array($h, (array) $registry->done, true)) { $reason = 'Already printed'; } else { foreach ($active as $other) { if ($other !== $h && isset($registry->registered[$other]) && in_array($h, (array) $registry->registered[$other]->deps, true)) { $reason = 'Required by ' . $other; break; } } } if (!$reason) { if ($kind === 'js') { wp_dequeue_script($h); } else { wp_dequeue_style($h); } self::$decisions[$key] = 'Disabled'; } else { self::$decisions[$key] = 'Kept: ' . $reason; } } } } // Keep only SQL structure: quoted literals, comments, numbers and hex values are removed. public static function fingerprint($sql) { $out = ''; $n = strlen($sql); for ($i = 0; $i < $n; $i++) { $c = $sql[$i]; if ($c === "'" || $c === '"') { $quote = $c; $out .= '?'; while (++$i < $n) { if ($sql[$i] === '\\') { $i++; continue; } if ($sql[$i] === $quote) { if ($i + 1 < $n && $sql[$i + 1] === $quote) { $i++; continue; } break; } } } elseif ($c === '#' || ($c === '-' && substr($sql, $i, 2) === '--')) { while ($i < $n && $sql[$i] !== "\n") { $i++; } $out .= ' '; } elseif ($c === '/' && substr($sql, $i, 2) === '/*') { $end = strpos($sql, '*/', $i + 2); $i = $end === false ? $n : $end + 1; $out .= ' '; } else { $out .= $c; } } $out = preg_replace('/\b(?:0x[0-9a-f]+|\d+(?:\.\d+)?)\b/i', '?', $out); return substr(trim(preg_replace('/\s+/', ' ', $out)), 0, 1500); } public static function query_advice($sql, $ms, $count) { if ($count > 1) { return 'Repeated similar requests: inspect callers for N+1 loops; batch reads or cache reusable results. Different parameter values can share a shape.'; } if (stripos($sql, 'postmeta') !== false && stripos($sql, 'JOIN') !== false) { return 'Review meta joins and EXPLAIN on staging; consider WooCommerce lookup tables. Do not add indexes blindly.'; } if (stripos($sql, 'options') !== false && stripos($sql, 'autoload') !== false) { return 'Audit autoloaded options by size and owner; remove only confirmed obsolete settings.'; } if ($ms >= 20) { return 'Slow query: inspect the caller and an EXPLAIN plan on staging; evaluate indexes, result size and cacheability.'; } return 'No automatic change recommended. Compare total time and repeated requests before optimizing.'; } public static function collect() { global $wpdb; $all = array_slice((array) $wpdb->queries, self::$query_start); $total = 0; $groups = array(); foreach ($all as $q) { $shape = self::fingerprint($q[0]); $key = hash('sha256', $shape); $ms = (float) $q[1] * 1000; $total += $ms; if (!isset($groups[$key])) { $groups[$key] = array('sql' => $shape, 'count' => 0, 'total_ms' => 0, 'max_ms' => 0, 'callers' => array()); } $groups[$key]['count']++; $groups[$key]['total_ms'] += $ms; $groups[$key]['max_ms'] = max($groups[$key]['max_ms'], $ms); } $rows = array(); foreach ($all as $q) { $shape = self::fingerprint($q[0]); $ms = round((float) $q[1] * 1000, 3); $frames = isset($q[4]['slxp']) ? $q[4]['slxp'] : array(); $first = $frames ? $frames[0] : array('owner' => 'Core / caller unavailable', 'file' => '', 'line' => 0); $key = hash('sha256', $shape); $groups[$key]['callers'][$first['owner']] = true; $rows[] = array('sql' => $shape, 'ms' => $ms, 'owner' => $first['owner'], 'file' => $first['file'], 'line' => $first['line'], 'frames' => $frames, 'elements' => isset($q[4]['slxp_elements']) ? $q[4]['slxp_elements'] : array(), 'repeat_count' => $groups[$key]['count'], 'shape_total_ms' => round($groups[$key]['total_ms'], 3), 'solution' => self::query_advice($shape, $ms, $groups[$key]['count'])); } usort($rows, function($a, $b) { return $b['ms'] <=> $a['ms']; }); $groups = array_values($groups); usort($groups, function($a, $b) { return $b['total_ms'] <=> $a['total_ms']; }); $assets = self::$assets; foreach (self::$decisions as $key => $decision) { if (isset($assets[$key])) { $assets[$key]['state'] = $decision; } } $s = self::settings(); return array('id' => self::$id, 'created' => gmdate('c'), 'url' => self::safe_url(home_url(self::relative_path())), 'path' => self::current_path(), 'mode' => self::$baseline ? 'baseline' : 'trial', 'settings_hash' => substr(hash('sha256', wp_json_encode($s)), 0, 12), 'php_ms' => round((microtime(true) - self::$start) * 1000, 2), 'query_ms' => round($total, 2), 'query_count' => count($all), 'query_rows_truncated' => count($rows) > 500, 'queries' => array_slice($rows, 0, 500), 'groups' => array_slice($groups, 0, 100), 'memory_mb' => round(memory_get_peak_usage(true) / 1048576, 2), 'assets' => array_values($assets), 'http' => self::$http, 'protected_route' => self::protected_route(), 'object_cache' => wp_using_ext_object_cache(), 'coverage' => defined('SAVEQUERIES') && SAVEQUERIES ? 'Queries after plugins_loaded priority 0 only; early bootstrap, separate AJAX and REST SQL are not captured.' : 'SAVEQUERIES is already false. Query timings unavailable; no override applied.', 'settings' => $s, 'version' => self::VERSION); } private static function relative_path() { $base = rtrim((string) wp_parse_url(home_url('/'), PHP_URL_PATH), '/'); $path = self::current_path(); if ($base && $path === $base) { return '/'; } return $base && strpos($path, $base . '/') === 0 ? substr($path, strlen($base)) : $path; } public static function inspector() { if (!self::$profile) { return; } $boot = array('id' => self::$id, 'endpoint' => rest_url('slxp/v1/'), 'nonce' => wp_create_nonce('wp_rest'), 'editor' => admin_url('post.php'), 'dashboard' => admin_url('tools.php?page=slxp'), 'mode' => self::$baseline ? 'baseline' : 'trial', 'path' => self::current_path()); echo ''; } public static function finish() { if (!self::$profile) { return; } self::$report = self::collect(); set_transient('slxp_' . self::$uid . '_' . self::$id, self::$report, DAY_IN_SECONDS); $ids = (array) get_user_meta(self::$uid, 'slxp_reports', true); array_unshift($ids, self::$id); foreach (array_slice($ids, 20) as $old) { delete_transient('slxp_' . self::$uid . '_' . $old); } update_user_meta(self::$uid, 'slxp_reports', array_slice($ids, 0, 20)); } public static function permission() { return current_user_can('manage_options'); } public static function rest() { register_rest_route('slxp/v1', '/report/(?P[a-f0-9-]{36})', array( array('methods' => 'GET', 'callback' => array(__CLASS__, 'get_report'), 'permission_callback' => array(__CLASS__, 'permission')), array('methods' => 'POST', 'callback' => array(__CLASS__, 'client_report'), 'permission_callback' => array(__CLASS__, 'permission')), )); register_rest_route('slxp/v1', '/editor-link', array('methods' => 'GET', 'callback' => array(__CLASS__, 'editor_link'), 'permission_callback' => array(__CLASS__, 'permission'))); register_rest_route('slxp/v1', '/rule', array('methods' => 'POST', 'callback' => array(__CLASS__, 'rule'), 'permission_callback' => array(__CLASS__, 'permission'))); } public static function editor_link($request) { if (!isset($request['id']) || !is_string($request['id']) || !preg_match('/^[a-f0-9-]{36}$/', $request['id'])) { return new WP_Error('slxp_id', 'Invalid capture ID.', array('status'=>400)); } $report = get_transient('slxp_' . get_current_user_id() . '_' . $request['id']); if (!$report) { return new WP_Error('slxp_missing', 'This capture expired. Create a new capture.', array('status'=>404)); } if ((defined('DISALLOW_FILE_EDIT') && DISALLOW_FILE_EDIT) || (defined('DISALLOW_FILE_MODS') && DISALLOW_FILE_MODS)) { return new WP_Error('slxp_disabled', 'File editing is disabled by this site. Ask your developer to use the displayed file path in their hosting editor.', array('status'=>403)); } $file = ''; $line = 1; if (isset($request['query'])) { $index = filter_var($request['query'], FILTER_VALIDATE_INT); $frame = isset($request['frame']) ? filter_var($request['frame'], FILTER_VALIDATE_INT) : 0; if ($index !== false && $index >= 0 && $frame !== false && $frame >= 0 && isset($report['queries'][$index]['frames'][$frame])) { $entry = $report['queries'][$index]['frames'][$frame]; $file = self::resolve_source($entry['file']); $line = max(1, min(1000000, (int) $entry['line'])); } } elseif (isset($request['asset']) || isset($request['resource'])) { $is_asset = isset($request['asset']); $index = filter_var($request[$is_asset ? 'asset' : 'resource'], FILTER_VALIDATE_INT); $rows = $is_asset ? $report['assets'] : (isset($report['client']['resources']) ? $report['client']['resources'] : array()); if ($index !== false && $index >= 0 && isset($rows[$index])) { $file = self::resolve_source(self::safe_url($rows[$index]['url']), true); } } $real = $file ? realpath($file) : false; if (!$real || !is_file($real) || !in_array(strtolower(pathinfo($real, PATHINFO_EXTENSION)), array('php','css','js','html','htm','json','txt'), true)) { return new WP_Error('slxp_file', 'No editable local source file was found. Create a fresh capture if this report predates the update. Generated or external files may not have an editor link.', array('status'=>400)); } if (!function_exists('get_plugins')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } foreach (get_plugins() as $main => $info) { foreach (get_plugin_files($main) as $relative) { if (realpath(WP_PLUGIN_DIR . '/' . $relative) !== $real) { continue; } if (!current_user_can('edit_plugins')) { return new WP_Error('slxp_permission', 'Your account cannot edit plugin files. Ask an administrator.', array('status'=>403)); } return array('url'=>add_query_arg(array('file'=>$relative,'plugin'=>$main,'slxp_line'=>$line), self_admin_url('plugin-editor.php')), 'line'=>$line); } } foreach (wp_get_themes() as $slug => $theme) { $root = realpath($theme->get_stylesheet_directory()); if (!$root || strpos($real, $root . DIRECTORY_SEPARATOR) !== 0) { continue; } if (!current_user_can('edit_themes')) { return new WP_Error('slxp_permission', 'Your account cannot edit theme files. Ask an administrator.', array('status'=>403)); } $relative = str_replace(DIRECTORY_SEPARATOR, '/', substr($real, strlen($root)+1)); return array('url'=>add_query_arg(array('file'=>$relative,'theme'=>$slug,'slxp_line'=>$line), self_admin_url('theme-editor.php')), 'line'=>$line); } return new WP_Error('slxp_scope', 'This file is not available in the WordPress plugin/theme editor. Use the displayed path in your hosting editor.', array('status'=>400)); } public static function get_report($request) { $r = get_transient('slxp_' . get_current_user_id() . '_' . $request['id']); if (!$r) { return new WP_Error('slxp_missing', 'Report not ready or expired (24 hours).', array('status' => 404)); } $response = rest_ensure_response($r); $response->header('Cache-Control', 'no-store, private'); return $response; } public static function client_report($request) { $key = 'slxp_' . get_current_user_id() . '_' . $request['id']; $r = get_transient($key); if (!$r) { return new WP_Error('slxp_missing', 'Report not ready or expired.', array('status' => 404)); } if (strlen($request->get_body()) > 250000) { return new WP_Error('slxp_size', 'Report too large.', array('status' => 413)); } $input = $request->get_json_params(); $client = array('resources' => array()); foreach (array('pre_request_ms','html_download_ms','dns_ms','connection_ms','tls_ms','redirect_ms','html_encoded','html_decoded','html_transfer','server_response_ms','document_ms','ttfb_ms','load_ms','dom_ms','lcp_ms','cls','long_tasks_ms','viewport_width','viewport_height') as $k) { $client[$k] = isset($input[$k]) && is_numeric($input[$k]) ? max(0, min(1000000000, (float) $input[$k])) : null; } foreach (array_slice(isset($input['resources']) && is_array($input['resources']) ? $input['resources'] : array(), 0, 500) as $row) { if (!is_array($row)) { continue; } $v = array('url' => self::safe_url(isset($row['url']) && is_string($row['url']) ? substr($row['url'], 0, 2000) : ''), 'type' => sanitize_key(isset($row['type']) && is_string($row['type']) ? $row['type'] : 'other'), 'label' => !empty($row['fragments']) ? 'Cart fragments request' : ''); foreach (array('ms', 'transfer', 'encoded', 'decoded') as $k) { $v[$k] = isset($row[$k]) && is_numeric($row[$k]) ? max(0, min(1000000000, (float) $row[$k])) : 0; } foreach (array('start_ms','wait_ms','download_ms') as $k) { $v[$k] = isset($row[$k]) && is_numeric($row[$k]) ? max(0, min(1000000000, (float) $row[$k])) : null; } $client['resources'][] = $v; } $r['client'] = $client; set_transient($key, $r, DAY_IN_SECONDS); return array('saved' => true); } public static function rule($request) { $p = $request->get_json_params(); $id = isset($p['id']) && is_string($p['id']) ? $p['id'] : ''; $r = get_transient('slxp_' . get_current_user_id() . '_' . $id); if (!$r) { return new WP_Error('slxp_report', 'Capture a report first.', array('status' => 400)); } $handle = isset($p['handle']) && is_string($p['handle']) ? $p['handle'] : ''; $kind = isset($p['kind']) && is_string($p['kind']) ? $p['kind'] : ''; $found = false; foreach ($r['assets'] as $a) { if ($a['handle'] === $handle && $a['kind'] === $kind) { $found = true; } } if (!$found || self::protected_handle($handle) || !in_array($kind, array('js','css'), true)) { return new WP_Error('slxp_protected', 'Unknown or protected asset.', array('status' => 400)); } $s = self::settings(); // Rule edits from the inspector never change visitor behavior silently. if ($s['live']) { return new WP_Error('slxp_live', 'Turn off visitor rules in the dashboard before editing test settings.', array('status' => 409)); } $rules = array_values(array_filter($s['rules'], function($v) use ($r, $kind, $handle) { return !($v['path'] === $r['path'] && $v['kind'] === $kind && $v['handle'] === $handle); })); if (!empty($p['disable'])) { if (count($rules) >= 100) { return new WP_Error('slxp_limit', '100-rule limit reached.', array('status'=>400)); } $rules[] = array('path' => $r['path'], 'kind' => $kind, 'handle' => $handle); } $s['rules'] = $rules; update_option(self::OPTION, $s, false); return array('saved' => true); } public static function menu() { add_management_page('LagReveal', 'LagReveal', 'manage_options', 'slxp', array(__CLASS__, 'page')); } public static function admin_assets($hook) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only line focus; editor writes are protected by WordPress. if (in_array($hook, array('plugin-editor.php','theme-editor.php'), true) && isset($_GET['slxp_line']) && current_user_can($hook === 'plugin-editor.php' ? 'edit_plugins' : 'edit_themes')) { wp_enqueue_script('slxp-editor-focus', plugins_url('assets/editor-focus.js', __FILE__), array(), self::VERSION, true); } if ($hook === 'tools_page_slxp') { wp_enqueue_style('slxp-admin', plugins_url('assets/admin.css', __FILE__), array(), self::VERSION); } } public static function bar($bar) { if (is_admin() || !current_user_can('manage_options')) { return; } $url = add_query_arg(array('slxp_profile'=>'baseline','_slxp'=>wp_create_nonce('slxp_profile')), home_url(self::relative_path())); $bar->add_node(array('id'=>'slxp','title'=>'Profile this page','href'=>$url)); } public static function save() { if (!current_user_can('manage_options')) { wp_die('Administrator access required.', '', array('response'=>403)); } check_admin_referer('slxp_admin'); $s = self::settings(); if (isset($_POST['reset'])) { $s = self::defaults(); } else { $s['live'] = !empty($_POST['live']); $mode = self::text_param($_POST, 'fragments'); $s['fragments'] = in_array($mode, array('default','shop','off'), true) ? $mode : 'default'; foreach (array('emoji','embeds','heartbeat') as $k) { $s[$k] = !empty($_POST[$k]); } if (isset($_POST['remove']) && is_scalar($_POST['remove'])) { unset($s['rules'][absint($_POST['remove'])]); $s['rules'] = array_values($s['rules']); } } update_option(self::OPTION, $s, false); wp_safe_redirect(admin_url('tools.php?page=slxp&saved=1')); exit; } public static function launch() { if (!current_user_can('manage_options')) { wp_die('Administrator access required.', '', array('response'=>403)); } check_admin_referer('slxp_admin'); $target = esc_url_raw(self::text_param($_POST, 'url')); $home = wp_parse_url(home_url('/')); $p = wp_parse_url($target); if (!$p || !isset($p['host']) || strtolower($p['host']) !== strtolower($home['host']) || ($p['scheme'] ?? '') !== ($home['scheme'] ?? '') || ($p['port'] ?? null) !== ($home['port'] ?? null) || isset($p['user']) || isset($p['pass'])) { wp_die('Use a frontend URL on this site.'); } $base = rtrim($home['path'] ?? '', '/'); $path = $p['path'] ?? '/'; if ($base && $path !== $base && strpos($path, $base . '/') !== 0) { wp_die('URL must belong to this WordPress installation.'); } parse_str($p['query'] ?? '', $query); foreach (array('add-to-cart','wc-ajax','wc-api','rest_route','action','key','pay_for_order') as $k) { if (isset($query[$k])) { wp_die('Use a read-only page URL, not an action or transaction URL.'); } } if (preg_match('~/(wp-admin|wp-login\.php|wp-json)(/|$)~', $path)) { wp_die('Use a frontend page URL.'); } $mode = self::text_param($_POST, 'mode') === 'trial' ? 'trial' : 'baseline'; wp_safe_redirect(add_query_arg(array('slxp_profile'=>$mode,'_slxp'=>wp_create_nonce('slxp_profile')), $target)); exit; } public static function page() { if (!current_user_can('manage_options')) { return; } $s = self::settings(); $reports = array(); foreach ((array) get_user_meta(get_current_user_id(), 'slxp_reports', true) as $id) { $r = get_transient('slxp_' . get_current_user_id() . '_' . $id); if ($r) { $reports[] = $r; } } echo '
LAGREVEAL

By SoftLinkx

Measure. Test. Improve.

Trace frontend cost before changing your website. Version ' . esc_html(self::VERSION) . ' · developer preview

'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only status message; no state is changed. if (isset($_GET['saved'])) { echo '

Settings saved. Purge page/CDN caches after changing visitor rules. Profiled administrator pages bypass cache where supported.

'; } if (self::disabled()) { echo '

Emergency bypass is active: SLX_PERF_DISABLE. Profiling and optimizations are off.

'; } echo '

1. Capture a frontend page

First measure current performance with this plugin’s optimization rules bypassed. Then use Test optimizations to apply your selected changes privately. Interact with menus, search, and the cart; press Capture again in the inspector. Reports are private to your administrator account and expire after 24 hours.

'; wp_nonce_field('slxp_admin'); echo '

Logged-in, instrumented measurements are not anonymous cached benchmarks. SQL capture starts at plugins_loaded; file attribution is the nearest observed plugin/theme caller, not exclusive plugin CPU time.

'; echo '

2. Reversible controls

'; wp_nonce_field('slxp_admin'); echo '

Off = rules run only in administrator optimization tests. Cart, checkout, account, AJAX and REST are excluded. Publish only after validating a complete purchase flow.

This suppresses fragment execution, not necessarily the JS download. A classic header mini-cart can become stale. Mini-Cart Blocks use the Store API and are unaffected.

'; foreach (array('emoji'=>'Disable extra emoji support','embeds'=>'Disable embedded post previews','heartbeat'=>'Disable background update checks') as $k=>$label) { echo '

' . esc_html(array('emoji'=>'Stops WordPress loading its extra emoji support. Modern browsers can still display standard emoji.', 'embeds'=>'Removes the WordPress script used for embedded post previews. Test embedded content after enabling.', 'heartbeat'=>'Stops periodic WordPress background updates on frontend pages. Check any features requiring live updates.')[$k]) . '

'; } echo '

Per-page asset rules

Add JS/CSS rules from a captured frontend report. Paths match exactly, ignoring query strings.

'; foreach ($s['rules'] as $i=>$r) { echo '

' . esc_html($r['path'].' · '.$r['kind'].' · '.$r['handle']) . '

'; } echo '

Recent captures

Last 20 captures for your account. Download reports from the frontend inspector. Zero resource bytes can mean browser cache or cross-origin restrictions.

'; foreach ($reports as $r) { echo ''; } if (!$reports) { echo ''; } echo '
Page / timeModePHP windowSQLQueriesBrowser TTFBReport
' . esc_html($r['path']) . '
' . esc_html($r['created']) . '
' . esc_html(self::mode_label($r['mode'])) . '' . esc_html(self::timing($r['php_ms'])) . '' . esc_html(self::timing($r['query_ms'])) . '' . (int)$r['query_count'] . '' . esc_html(isset($r['client']['ttfb_ms']) ? self::timing($r['client']['ttfb_ms']) : 'Not captured') . '' . esc_html(substr($r['id'],0,8)) . '
No captures yet. Measure current performance above.
'; if (count($reports)>=2) { $a=$reports[1]; $b=$reports[0]; if ($a['path']===$b['path'] && $a['mode']!==$b['mode']) { $base=$a['mode']==='baseline'?$a:$b; $trial=$a['mode']==='trial'?$a:$b; echo '

Current performance → optimization test: ' . esc_html($base['path']) . '

PHP window change: ' . esc_html(self::timing($trial['php_ms']-$base['php_ms'])) . ' · SQL change: ' . esc_html(self::timing($trial['query_ms']-$base['query_ms'])) . '. Negative is lower. Repeat at least three times with the same viewport, cache state and interactions; single runs are noisy.

'; } } echo '
'; if ($reports) { echo '

Inspect a saved capture: '; foreach ($reports as $saved_link) { echo '' . esc_html(substr($saved_link['id'],0,8) . ' · ' . self::mode_label($saved_link['mode'])) . ' '; } echo '

'; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only selection from the current administrator's private reports. $selected_capture = self::text_param($_GET, 'capture'); if (!$selected_capture && $reports) { $selected_capture = $reports[0]['id']; } foreach ($reports as $saved) { if ($saved['id'] !== $selected_capture) { continue; } echo '
Inspect capture ' . esc_html(substr($saved['id'],0,8) . ' · ' . self::mode_label($saved['mode']) . ' · ' . $saved['path']) . '

' . esc_html($saved['coverage']) . '

Slowest queries

'; foreach ($saved['queries'] as $q) { echo ''; } echo '
DurationOwner / fileSimilar querySuggestion
' . esc_html(self::timing($q['ms'])) . '' . esc_html($q['owner']) . '
' . esc_html($q['file'] . ':' . $q['line']) . '
' . esc_html($q['sql']) . '' . esc_html($q['solution']) . '

Assets

'; foreach ($saved['assets'] as $a) { echo ''; } echo '
HandleOwner / URLState
' . esc_html($a['kind'] . ' · ' . $a['handle']) . '' . esc_html($a['owner']) . '
' . esc_html($a['url']) . '
' . esc_html($a['state']) . '
'; } self::health_panel(); echo '

Measurement boundaries & recovery

SQL is shown as database requests with private values hidden, with a maximum of 500 slowest rows and 100 groups per report. Requests made by AJAX/REST have network timing only, not their server SQL. Resource duration is network elapsed time, not JavaScript execution time. Hardcoded or rewritten assets may not map to a WordPress handle.

No database query is suppressed and no plugin is deactivated. Optimize the responsible feature after reviewing its caller. No reports are sent to an external service.

Emergency bypass: add define(\'SLX_PERF_DISABLE\', true); before WordPress loads in wp-config.php, or deactivate this plugin. Purge page/CDN caches to remove previously cached asset omissions.

'; } private static function health_panel() { $autoload = wp_load_alloptions(); $bytes = 0; $sizes=array(); foreach ($autoload as $name=>$value) { $size = strlen(is_scalar($value) ? (string)$value : serialize($value)); $bytes += $size; $sizes[$name]=$size; } arsort($sizes); $op = function_exists('opcache_get_status') ? @opcache_get_status(false) : false; echo '

Server opportunities

Autoloaded options: ' . count($autoload) . ' / approximately ' . esc_html(round($bytes/1024,1)) . ' KB. Persistent object cache: ' . (wp_using_ext_object_cache()?'enabled':'not detected') . '. OPcache: ' . (!$op?'unavailable':(!empty($op['cache_full'])?'full — ask host to review capacity':'enabled')) . '.

Option names and sizes only; values are never displayed. Names do not reliably identify an owning plugin. Review ownership before changing autoload behavior.

Largest autoloaded options'; foreach (array_slice($sizes,0,20,true) as $name=>$size) { echo ''; } echo '
Option nameKB
' . esc_html($name) . '' . esc_html(round($size/1024,1)) . '
'; } }