includes/Insight/class-rum.php
Real-user Web Vitals (RUM) collection and reporting.
Class RUM
Collects real-visitor Core Web Vitals beacons and stores them as bounded per-day/per-path aggregates, plus the frontend beacon + admin data API.
class RUMConstants
| Constant | Visibility | Value | Line |
|---|---|---|---|
OPTION | public | \'wppo_web_vitals_rum\' | 33 |
MAX_DAYS | public | 14 | 40 |
MAX_PATHS_PER_DAY | public | 200 | 47 |
MAX_TOTAL_PATHS | public | 600 | 59 |
MAX_OPTION_BYTES | public | 491520 | 67 |
RATE_LIMIT_PER_HOUR | public | 120 | 74 |
GLOBAL_RATE_LIMIT_PER_MINUTE | public | 120 | 82 |
RUM_SAMPLE_RATE_DEFAULT | public | 100 | 93 |
RUM_THROTTLE_THRESHOLD_DEFAULT | public | 60 | 109 |
QUEUE_KEY | private | \'wppo_rum_queue\' | 117 |
FLUSH_LOCK_KEY | private | \'wppo_rum_flush_lock\' | 125 |
QUEUE_MAX | private | 100 | 133 |
MAX_LCP_URLS_PER_PATH | public | 10 | 144 |
MAX_LCP_SEGMENTS_PER_PATH | public | 6 | 155 |
MAX_LCP_SAMPLES_PER_SEGMENT | public | 100 | 166 |
MAX_INP_SEGMENTS_PER_PATH | public | 6 | 178 |
MAX_INP_SAMPLES_PER_SEGMENT | public | 100 | 189 |
LCP_URL_MAX_LENGTH | public | 2048 | 197 |
LCP_SELECTOR_MAX_LENGTH | public | 256 | 205 |
SLOW_RESOURCES_MAX_COUNT | public | 5 | 213 |
SLOW_RESOURCE_URL_MAX_LENGTH | public | 2048 | 221 |
SLOW_RESOURCE_MAX_DURATION_MS | public | 60000 | 229 |
MAX_LCP_SELECTORS_PER_PATH | public | 10 | 240 |
MAX_SLOW_RESOURCES_PER_PATH | public | 10 | 251 |
ALLOWED_SLOW_RESOURCE_TYPES | public | array( \'img\', \'script\', \'css\', \'link\', \'font\', \'fetch\', \'xmlhttprequest\', \'iframe\' ) | 262 |
ALLOWED_CONNECTIONS | public | array( \'slow-2g\', \'2g\', \'3g\', \'4g\' ) | 274 |
FIELD_LCP_DEFAULT_MIN_SAMPLES | public | 20 | 285 |
FIELD_LCP_MIN_SAMPLES_MAX | public | 1000 | 299 |
FIELD_LCP_STALE_TTL | public | 86400 | 311 |
FLUSH_THRESHOLD | private | 20 | 384 |
Properties
| Property | Visibility | Type | Default | Line |
|---|---|---|---|---|
$field_lcp_aggregate | private static | ?array | null | 325 |
$field_lcp_loaded | private static | bool | false | 333 |
$field_lcp_result_memo | private static | array | array() | 342 |
$score_trends_memo | private static | ?array | null | 356 |
$score_trends_loaded | private static | bool | false | 364 |
$top_url_generation | private static | int | -1 | 376 |
$stored_lcp_memo | private static | array<string, | array() | 2867 |
publicstatic is_enabled()
public static function is_enabled(): boolWhether RUM collection is enabled.
Return: bool.
publicstatic clear_field_lcp_cache()
public static function clear_field_lcp_cache(): voidClear the per-request field-LCP memo.
Return: void.
privatestatic top_url_generation()
private static function top_url_generation(): intCurrent generation for the per-path top-URL index.
Return: int — Generation counter.
privatestatic top_url_cache_key()
private static function top_url_cache_key(string $normalized_path, int $min): stringTransient key for the per-path top-URL index entry. Parameter Type Default Description $normalized_pathstring— Normalized page path. $minint— Sample gate.
Return: string — Transient key (unprefixed; wrap with Util::transient_key()).
privatestatic bump_top_url_generation()
private static function bump_top_url_generation(): voidBump the top-URL index generation so flush-invalidated entries expire.
Return: void.
privatestatic get_memoized_aggregate()
private static function get_memoized_aggregate(): arrayGet the RUM aggregate with a per-request memo.
Return: array — Aggregate data (empty array when missing/invalid).
privatestatic ensure_field_lcp_cache_hook()
private static function ensure_field_lcp_cache_hook(): voidRegister invalidation hooks for the RUM aggregate memo (once per request).
Return: void.
publicstatic migrate_rum_autoload()
public static function migrate_rum_autoload(): voidMigrate the RUM aggregate option to non-autoloading.
Return: void.
publicstatic collect()
public static function collect(array $params): arrayHandle a RUM beacon. Parameter Type Default Description $paramsarray— Decoded JSON body from the beacon request.
Return: array{ok:bool,status:int,message:string}.
publicstatic get_data()
public static function get_data(): arrayRetrieve the aggregated RUM data for the admin dashboard.
Return: array.
publicstatic get_aggregate_readonly()
public static function get_aggregate_readonly(): arrayRetrieve the aggregated RUM data without side effects (read-only).
Return: array — Aggregate data (empty array when missing/invalid).
publicstatic maybe_enqueue_scripts()
public static function maybe_enqueue_scripts(): voidEnqueue the frontend beacon script on the public site.
Return: void.
privatestatic supports_script_strategy()
private static function supports_script_strategy(): boolWhether core supports the native `strategy` script args (WP 6.3+).
Return: bool.
publicstatic print_config()
public static function print_config(): voidPrint the beacon config inline so it is baked into cached HTML.
Return: void.
privatestatic detect_template_slug()
private static function detect_template_slug(): stringDetect the current template slug for RUM segmentation.
Return: string — Template slug (max 64 chars) or \’\’.
privatestatic token_for()
private static function token_for(int $timestamp, string=\'/\' $path): stringRolling daily token for the beacon, scoped to the page path. Parameter Type Default Description $timestampint— Unix timestamp. $pathstring=\'/\'— Page path the token is minted for.
Return: string.
privatestatic is_valid_token()
private static function is_valid_token(string $token, string=\'/\' $path): boolValidate the beacon token against today or yesterday for the given path. Parameter Type Default Description $tokenstring— Beacon token. $pathstring=\'/\'— Page path the beacon was served on.
Return: bool.
privatestatic is_rate_limited()
private static function is_rate_limited(string $ip): boolWhether the given IP has exceeded the hourly beacon budget. Parameter Type Default Description $ipstring— Client IP address.
Return: bool.
privatestatic normalize_ip()
private static function normalize_ip(string $ip): stringNormalize a client IP for rate-limit keying. Parameter Type Default Description $ipstring— Raw IP string.
Return: string — Normalized IP or \’\’.
privatestatic is_globally_rate_limited()
private static function is_globally_rate_limited(): boolWhether the site-wide per-minute beacon budget is exhausted.
Return: bool.
publicstatic get_sample_rate()
public static function get_sample_rate(): intConfigured RUM beacon sample rate (percent of page views, 1-100).
Return: int — Sample rate in 1-100.
publicstatic get_effective_sample_rate()
public static function get_effective_sample_rate(): intEffective sample rate after the high-traffic auto-throttle.
Return: int — Effective rate in 1-100.
publicstatic should_keep_sample()
public static function should_keep_sample(?int=null $rate, ?int=null $roll): boolSampling decision for one beacon (lossy hint only, no PII). Parameter Type Default Description $rate?int=null— Sample rate in 1-100. Null resolves via get_effective_sample_rate(). $roll?int=null— Deterministic roll in 1-100. Null draws fresh randomness.
Return: bool — True when the beacon should be sent/stored.
privatestatic sanitize_sample()
private static function sanitize_sample(array $params): ?arrayValidate and clamp a beacon sample. Parameter Type Default Description $paramsarray— Raw beacon payload.
Return: array|null — Normalized sample or null when invalid.
publicstatic get_metric_ranges()
public static function get_metric_ranges(): arrayShared metric range table for sample validation.
Return: array<string,array{0:float,1:float}> — Metric => [min, max].
privatestatic clamp_metric_value()
private static function clamp_metric_value(string $metric, float $value): floatClamp a metric value to its valid range. Parameter Type Default Description $metricstring— Metric name. $valuefloat— Raw value (must be finite).
Return: float — Clamped value.
privatestatic normalize_segment()
private static function normalize_segment($raw, ?array $allowlist, int $maxlen): stringNormalize a raw segment value against an allowlist. Parameter Type Default Description $rawmixed— Raw value. $allowlist?array— Allowed values (null = free-form slug). $maxlenint— Max length before normalization.
Return: string — Normalized segment or \’unknown\’.
privatestatic get_home_host()
private static function get_home_host(): stringResolve the home host (lowercased) for same-origin checks.
Return: string — Home host or \’\’.
privatestatic is_scheme_like_url()
private static function is_scheme_like_url(string $url): boolWhether a URL is scheme-like (can never be same-origin relative). Parameter Type Default Description $urlstring— Candidate URL.
Return: bool — True when scheme-like.
privatestatic normalize_segment_device()
private static function normalize_segment_device($raw): stringNormalize a device value to the segment allowlist. Parameter Type Default Description $rawmixed— Raw device value.
Return: string — Allowlisted device or \’unknown\’.
privatestatic normalize_segment_template()
private static function normalize_segment_template($raw): stringNormalize a template slug to the segment allowlist shape. Parameter Type Default Description $rawmixed— Raw template value.
Return: string — Sanitized template slug (max 64 chars) or \’unknown\’.
privatestatic normalize_segment_connection()
private static function normalize_segment_connection($raw): stringNormalize a queued-sample connection value to the segment allowlist. Parameter Type Default Description $rawmixed— Raw connection value from a queued sample.
Return: string — Allowlisted connection type or \’unknown\’.
privatestatic sanitize_lcp_selector()
private static function sanitize_lcp_selector($raw): stringSanitize an LCP element selector attribution value. Parameter Type Default Description $rawmixed— Raw selector value.
Return: string — Sanitized selector or \’\’.
privatestatic normalize_slow_resource_type()
private static function normalize_slow_resource_type($raw): stringNormalize a slow-resource initiator type to the allowlist. Parameter Type Default Description $rawmixed— Raw initiator type.
Return: string — Allowlisted type or \’\’.
privatestatic sanitize_slow_resources()
private static function sanitize_slow_resources($raw): arraySanitize the slow-resource audit payload. Parameter Type Default Description $rawmixed— Raw slowResources value.
Return: array — Shaped entries (possibly empty).
privatestatic is_safe_lcp_url()
private static function is_safe_lcp_url(string $lcp_url): boolWhether a candidate LCP element URL is safe to store. Parameter Type Default Description $lcp_urlstring— Candidate LCP URL (already trimmed + length-capped).
Return: bool — True when safe to store.
privatestatic is_same_origin_lcp_url()
private static function is_same_origin_lcp_url(string $lcp_url): boolWhether an LCP element URL is same-origin with this site. Parameter Type Default Description $lcp_urlstring— Candidate LCP URL.
Return: bool — True when same-origin.
publicstatic is_same_origin_url()
public static function is_same_origin_url(string $url): boolWhether a URL is same-origin with this site (public emission guard). Parameter Type Default Description $urlstring— Candidate URL.
Return: bool — True when same-origin or unverifiable.
publicstatic is_same_origin_url_strict()
public static function is_same_origin_url_strict(string $url): boolWhether a URL is same-origin, strict variant for emission paths. Parameter Type Default Description $urlstring— Candidate URL.
Return: bool — True only when same-origin is positively proven.
privatestatic has_ext_object_cache()
private static function has_ext_object_cache(): boolWhether a persistent external object cache is available.
Return: bool — True when wp_using_ext_object_cache() reports a persistent cache.
privatestatic append_to_queue_atomic()
private static function append_to_queue_atomic(array $sample): arrayAtomically append a sample to the RUM queue. Parameter Type Default Description $samplearray— Normalized sample (with `_ts` attached).
Return: array{0:bool,1:int} — Tuple of (was_empty before append, count after append).
privatestatic acquire_flush_lock()
private static function acquire_flush_lock(): boolAtomically acquire the RUM flush lock.
Return: bool — True when this worker owns the lock.
privatestatic release_flush_lock()
private static function release_flush_lock(): voidRelease the RUM flush lock from both namespaces.
Return: void.
privatestatic merge_value_segment()
private static function merge_value_segment(array& $bucket, string $map_key, int $max_segments, int $max_samples, string $device, string $template, string $connection, float $value): voidMerge one value into a bounded per-path segment map. Parameter Type Default Description $bucketarray&— Bucket to merge into (by ref). $map_keystring— Segment map key (\’lcpSeg\’ or \’inpSeg\’). $max_segmentsint— Max segments per path. $max_samplesint— Max reservoir samples per segment. $devicestring— Normalized device. $templatestring— Normalized template. $connectionstring— Normalized connection. $valuefloat— Clamped metric value.
Return: void.
privatestatic validate_queued_sample()
private static function validate_queued_sample($sample): ?arrayValidate one queued sample into a merge-ready shape. Parameter Type Default Description $samplemixed— Raw queued entry.
Return: array{date:string,path:string,ts:int,sample:array}|null — Validated sample or null to skip.
privatestatic persist_aggregate()
private static function persist_aggregate(array $all): voidPersist aggregates with retention + size budgets. Parameter Type Default Description $allarray— Aggregates.
Return: void.
privatestatic store_sample()
private static function store_sample(array $sample): voidBuffer a sample to a transient queue and flush periodically. Parameter Type Default Description $samplearray— Normalized sample.
Return: void.
publicstatic flush_queue()
public static function flush_queue(): voidFlush queued RUM samples to the persistent aggregate option.
Return: void.
publicstatic get_field_lcp_url()
public static function get_field_lcp_url(?string=null $path): ?arrayGet the field-measured LCP URL for a page path. Parameter Type Default Description $path?string=null— Page path (e.g. \”/about/\”). Defaults to the current request path.
Return: array{url:string,n:int,lastSeen:int}|null — Top LCP URL entry or null.
publicstatic get_lcp_preload_candidate()
public static function get_lcp_preload_candidate(?string=null $path): ?arrayGet the single LCP preload candidate for a page path. Parameter Type Default Description $path?string=null— Page path (e.g. \”/about/\”). Defaults to the current request path.
Return: array{url:string,n:int,lastSeen:int}|null — Single LCP candidate or null.
publicstatic get_top_lcp_selector()
public static function get_top_lcp_selector(?string=null $path, ?int=null $min): ?arrayGet the top LCP element selector attribution for a page path. Parameter Type Default Description $path?string=null— Page path (e.g. \”/about/\”). Defaults to the current request path. $min?int=null— Minimum samples (defaults to get_field_lcp_min_samples()).
Return: array{selector:string,n:int,lastSeen:int}|null — Top selector or null.
publicstatic get_top_slow_resources()
public static function get_top_slow_resources(int=3 $limit): arrayGet the top slow-resource audit entries across the aggregate. Parameter Type Default Description $limitint=3— Maximum entries (1–10, defaults to 3).
Return: array<int,array{url:string,type:string,n:int,avgDuration:float,maxDuration:float,lastSeen:int}> — Top slow resources.
privatestatic resolve_current_path()
private static function resolve_current_path(): ?stringResolve the current page path the same way the preload pipeline does.
Return: string|null — Current page path or null when unresolvable.
publicstatic clear_stored_lcp_memo()
public static function clear_stored_lcp_memo(): voidClear the per-request stored-LCP memo.
Return: void.
privatestatic memo_store_lcp()
private static function memo_store_lcp(string $memo_key, string $value): voidStore one memo entry with a drop-oldest cap. Parameter Type Default Description $memo_keystring— Memo bucket key. $valuestring— LCP URL (or \’\’ for a negative).
Return: void.
publicstatic get_stored_pagespeed_lcp_url()
public static function get_stored_pagespeed_lcp_url(?string=null $path): stringRead-only lookup of the stored PageSpeed LCP candidate for a page. Parameter Type Default Description $path?string=null— Page path (e.g. \”/about/\”). Defaults to the current request URL.
Return: string — The PageSpeed LCP image URL, or empty string when none is stored.
publicstatic get_field_lcp_min_samples()
public static function get_field_lcp_min_samples(): intResolve the field-LCP minimum-sample threshold for auto-tune.
Return: int — Minimum samples (>=1).
publicstatic compute_p75()
public static function compute_p75(array $samples): floatCompute the p75 of a numeric sample list. Parameter Type Default Description $samplesarray— Numeric samples.
Return: float — p75 value or 0.0 when empty.
publicstatic get_field_p75_by_segment()
public static function get_field_p75_by_segment(string $seg_key, ?int=null $min_samples): arrayGet field p75 segmented by device × template × connection (read-only). Parameter Type Default Description $seg_keystring— Segment map key (\’lcpSeg\’ or \’inpSeg\’). $min_samples?int=null— Minimum samples per segment. Null resolves via get_field_lcp_min_samples().
Return: array[] — Rows of array(path,device,template,connection,n,p75).
publicstatic get_field_lcp_p75_by_segment()
public static function get_field_lcp_p75_by_segment(?int=null $min_samples): arrayGet field LCP p75 segmented by device × template × connection (read-only). Parameter Type Default Description $min_samples?int=null— Minimum samples per segment. Null resolves via get_field_lcp_min_samples().
Return: array[] — Rows of array(path,device,template,connection,n,p75).
publicstatic get_path_lcp_priority()
public static function get_path_lcp_priority(?int=null $min_samples): arrayGet worst p75 LCP per normalized path for CSS queue prioritization. Parameter Type Default Description $min_samples?int=null— Minimum samples per segment. Null resolves via get_field_lcp_min_samples().
Return: array<string, — float> Normalized path => worst p75 LCP in ms, worst-first order.
publicstatic score_url_lcp()
public static function score_url_lcp(string $url, ?array=null $priority, ?array=null $trends): floatScore a queue URL by worst p75 LCP (RUM path + trend blend). Parameter Type Default Description $urlstring— Candidate queue URL. $priority?array=null— — $trends?array=null— Optional pre-loaded Pagespeed::get_trends() map. Null loads (and per-request memos) it once.
Return: float — Worst p75 LCP in ms, or 0.0 when unknown.
publicstatic get_field_inp_p75_by_segment()
public static function get_field_inp_p75_by_segment(?int=null $min_samples): arrayGet field INP p75 segmented by device × template × connection (read-only). Parameter Type Default Description $min_samples?int=null— Minimum samples per segment. Null resolves via get_field_lcp_min_samples() (shared gate, default 20).
Return: array[] — Rows of array(path,device,template,connection,n,p75).
Hooks
Hooks referenced in includes/Insight/class-rum.php: Hook Type Line Notes wppo_rum_throttle_thresholdfilter 1018 — wppo_rum_effective_sample_ratefilter 1029 —