=== Empirical Responsive Images ===
Contributors: jesusinica
Tags: responsive images, image optimization, image sizes, webp, avif
Requires at least: 6.9
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 0.3.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Learns real WordPress image sizes, generates responsive thumbnails, and creates WebP/AVIF variants in the background.

== Description ==

Empirical Responsive Images is a WordPress responsive image optimization plugin that learns the image widths real visitors need. It generates matching responsive thumbnails in the background, registers evidence-backed image sizes for WordPress `srcset`, and creates WebP and AVIF variants when the server supports them.

Instead of pre-generating every possible size, the plugin measures real rendered image slots, confirms repeated demand, and creates only missing candidates. This helps WordPress serve properly sized images and can reduce oversized downloads that hurt Largest Contentful Paint (LCP), PageSpeed, and Core Web Vitals. Results depend on the site, theme, images, cache, and server.

= Responsive image optimization based on real demand =

WordPress sites often generate the same thumbnail set for every upload. Themes, plugins, responsive layouts, and device pixel ratios can still request widths that set does not cover well.

Empirical Responsive Images closes those measured gaps:

1. A local script checks existing candidates during browser idle time; covered images send no report.
2. Repeated gaps map to a fixed size palette and are verified by WordPress.
3. Qualified work enters a bounded WP-Cron queue.
4. The worker generates only missing attachment or local asset variants.
5. WordPress exposes better candidates through normal `srcset` and `sizes` markup.

No resize work runs in the browser. No image generation runs during the page response.

= What the plugin optimizes =

* Learns responsive image widths from real rendered slots instead of guesses.
* Registers proven WordPress image sizes and generates matching thumbnails.
* Supports Media Library attachments and manageable local theme or plugin images inside `wp-content`.
* Creates WebP and AVIF sidecars when the active GD or Imagick editor supports them.
* Preserves author-owned `srcset`, `sizes`, picture art direction, crop intent, animation, and sensitive transparency.
* Purges stale page markup after successful background generation so new candidates can appear.
* Provides status tables plus optional batch and WP-CLI regeneration tools.
* Uses no CDN and sends data to no external image optimization API.

= Performance without blocking visitors =

The browser performs a lightweight idle-time coverage check. Gap reports wait for visitor interaction or page exit, keeping them out of initial page navigation. The public request records evidence only; it never creates files.

WP-Cron processes as many qualified jobs as fit inside a default 30-second budget, then leaves the rest for the next run. Visitors do not wait for thumbnail or WebP/AVIF generation.

This plugin targets right-sized responsive delivery. It does not rewrite or recompress the original source image like a dedicated image compression tool.

== Privacy ==

Automatic learning is enabled by default. It checks signed local image targets during browser idle time; covered images make no request.

A gap report can contain an HMAC-signed local target, a fixed width bucket, and bounded viewport or slot buckets. Stored evidence contains no page URL, visitor identity, IP address, user agent, or referrer. Anonymous visitors and Subscribers omit cookies. Roles with `edit_posts` use same-origin authentication and a REST nonce only to prove capability.

The optional detailed observer requires `manage_options` and a REST nonce. It stores aggregate rendered-image data and canonical page paths, without query strings or raw IP addresses.

All processing stays on the WordPress site. The plugin makes no external service calls and transfers no observation or image data to a third party.

Learning stays enabled. The 30-day rule cleans only stale unconfirmed evidence and terminal failures. Settings, observations, and generated files remain after uninstall unless cleanup is enabled first.

== Abuse protection ==

The server never trusts a requested URL or arbitrary pixel width. Every target is signed, re-resolved locally, and checked again for missing coverage before work is queued.

Work is bounded by a 38-width palette per target, request, evidence, queue, source, retry, daily generation, width, locking, and free-space limits. Invalid reports and replays cannot consume accepted-work budget or buy priority.

Anonymous visitors and Subscribers must confirm a missing pair in three distinct 15-minute server windows by default. A nonce-authenticated user with `edit_posts` can confirm it once. WordPress decides trusted status on the server.

== Installation ==

1. Upload `empirical-responsive-images` to `/wp-content/plugins/`.
2. Activate the plugin.
3. Done. The plugin learns uncovered local image sizes and processes qualified gaps in the background.

Tools > Responsive Images shows status and advanced settings. Automatic learning needs no approval or promotion step.

== Screenshots ==

1. End-to-end workflow: observe real browser slots, confirm repeated demand, and generate proven WordPress responsive image sizes in the background.
2. Mobile Lighthouse and PageSpeed result on one test page before and after right-sized image optimization. Scores vary by run, site, and environment.
3. Privacy-conscious observation summary with aggregate counts plus WebP and AVIF support status.
4. Observed local assets with measured widths, rendered slots, and aggregate observation counts.
5. Automatic learning queue showing confirmation windows, recent evidence, and background thumbnail status.
6. Registered empirical image sizes with widths, height ranges, observations, viewports, DPRs, and evidence origin.

== WP-CLI ==

List observed image sizes:

`wp empirical-responsive-images sizes`

Generate thumbnails and modern-format sidecars:

`wp empirical-responsive-images regenerate --batch-size=10`

Force a rebuild:

`wp empirical-responsive-images regenerate --force`

== Frequently Asked Questions ==

= What makes this different from a normal WordPress image optimizer? =

Most image optimization plugins focus on compression or format conversion. Empirical Responsive Images focuses on responsive sizing: it learns which widths the rendered site actually needs, confirms the gaps, and generates matching candidates. It can also create WebP and AVIF sidecars locally when supported.

= Does this replace WordPress responsive images or srcset? =

No. It adds evidence-backed image sizes so WordPress has better candidates for its normal `srcset` and `sizes` output.

= Can it improve PageSpeed, LCP, or Core Web Vitals? =

It can reduce oversized image downloads by giving the browser a closer candidate, which can improve image-loading metrics such as LCP. The screenshot shows one real test page improving from 75 to 99 and LCP from 7.2 seconds to 2.3 seconds. Lighthouse scores vary, and the plugin cannot guarantee a particular score or Core Web Vitals result.

= Does it compress images? =

It creates right-sized image variants and optional WebP/AVIF sidecars. It does not recompress the original source image or replace a dedicated original-image compression workflow.

= Does it support WebP and AVIF? =

Yes, when the active WordPress GD or Imagick image editor can encode the requested format. Original-format fallback markup remains available.

= Does it handle theme or plugin image assets? =

Yes. Manageable local images inside `wp-content` can be observed, resized into `wp-content/uploads/empirical-responsive-images/assets/`, and served with empirical `srcset` and `sizes` output.

= Does page rendering create thumbnails or slow the response? =

No. Front-end rendering checks existing coverage and records qualified evidence. A locked WP-Cron worker generates image files later. Each cron run handles as much work as fits within its bounded runtime, then schedules the remainder.

= Does an administrator need to approve learned image sizes? =

No. Repeated gaps are verified, queued, generated, retried, and exposed automatically. The administration tables show status; they are not an approval queue.

= Do logged-in users need three confirmations? =

Subscribers do. By default, Contributors, Authors, Editors, Administrators, and custom roles with `edit_posts` can confirm a valid gap in one request when it carries a valid REST nonce. Without both capability and nonce checks, the normal multi-window threshold applies.

= What visitor data does automatic learning collect? =

Only a signed local image handle and bounded size evidence needed to identify an uncovered candidate. Gap evidence stores no page URL, visitor identity, IP address, user agent, or referrer. Anonymous and Subscriber reports omit cookies. Public requests never generate images directly.

= Can bots or one-pixel screen changes create endless image sizes? =

No. Near matches count as covered, all remaining widths map to a fixed 38-entry palette, targets must be signed and local, and server-side request, queue, source, retry, storage, and daily work limits bound generation.

= Does automatic processing work on every host? =

The host needs writable uploads, a working WordPress cron runner, and GD or Imagick support for each requested output format. If WP-Cron is disabled, the host must invoke WordPress cron normally or queued work will wait.

= What happens when I uninstall the plugin? =

Data and generated files remain by default to prevent accidental loss. Enable uninstall cleanup under Tools > Responsive Images first if you want them removed.

== Changelog ==

= 0.3.4 =
* Rewrite the WordPress.org listing around responsive image optimization, evidence-backed image sizes, WebP/AVIF, PageSpeed, and user-focused FAQs without changing runtime behavior.
