=== HKC Performance ===
Contributors: hkabla
Plugin URI: https://plugins.hervekabla.com/hkc-performance/
Tags: core web vitals, pagespeed insights, performance, monitoring, search console
Requires at least: 6.2
Tested up to: 6.9
Requires PHP: 7.4
Stable tag: 0.3.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Surveillance des Core Web Vitals et de PageSpeed Insights depuis l'administration, sans rien charger sur le site public.

== Description ==

L'extension ajoute un menu « Performance » (interface en anglais) qui suit quelques pages de
référence : un score PageSpeed Insights mesuré par Google, les données réelles des visiteurs
Chrome, un historique, et des pistes de lecture.

**Deux mesures, deux usages**

* **Le test de laboratoire** (Lighthouse, via PageSpeed Insights) : un chargement simulé sur un
  téléphone moyen en 4G lente. Il sert au *diagnostic* : il dit quoi corriger.
* **Les données terrain** (Chrome UX Report, 28 derniers jours) : ce que vivent réellement les
  visiteurs. Ce sont elles que Google prend en compte, et que reprend le rapport « Signaux Web
  essentiels » de Search Console. Elles servent au *pilotage*.

Les Core Web Vitals sont LCP, INP et CLS. INP n'existe qu'en données terrain ; en laboratoire,
TBT en est l'approximation.

**Un score qui ne varie plus pour rien**

Un score mobile varie de 5 à 15 points d'un test à l'autre sans que rien ne change. L'extension :

* lance plusieurs passages en parallèle (trois par défaut) et retient le passage médian ;
* chauffe le cache de la page juste avant le test, avec un profil mobile ou ordinateur, pour ne
  pas mesurer une page générée à froid ;
* relève les en-têtes de cache (QUIC.cloud, LiteSpeed, Cloudflare…) et signale une couche de
  cache disparue depuis le contrôle précédent ;
* note la version de Lighthouse de chaque contrôle et marque ses changements sur le graphique :
  une marche à cet endroit vient plus probablement de Google que du site ;
* signale un écart mobile / ordinateur important sans en faire une alerte.

**Tableau de bord**

Pour chaque page et chaque appareil (mobile en premier) : score et jauge aux couleurs de Google,
six métriques de laboratoire avec leurs seuils, évaluation Core Web Vitals des vrais visiteurs
(de la page, ou du site entier si la page manque de trafic), courbe du score sur 90 jours,
pistes d'amélioration classées par impact estimé, capture de la page vue par Google, et
conditions de la mesure.

Le tableau de bord n'appelle jamais Google à l'affichage : il lit la base et s'affiche aussitôt.
Si un contrôle échoue (quota, délai), le dernier résultat réussi reste affiché avec la cause.

**Alertes**

Évaluées sur mobile à la fin de chaque contrôle, selon des seuils réglables : score sous un
minimum (70 par défaut), LCP, TBT ou CLS au-dessus d'un maximum, chute du score d'au moins
20 points par rapport à la médiane de la semaine précédente (et non au seul contrôle d'avant),
et, en option, échec de l'évaluation Core Web Vitals des vrais visiteurs. Une chute qui coïncide
avec un changement de version de Lighthouse ou avec une mise à jour du site le précise.

Une alerte s'affiche en bandeau dans toute l'administration (masquable jusqu'à la prochaine
alerte nouvelle) et par un compteur sur le menu. Un email, facultatif, ne part que pour une
alerte nouvelle, au plus un par 24 heures.

**Changements du site**

Mises à jour et activations d'extensions, de thèmes et de WordPress, réglages de LiteSpeed Cache
modifiés, et notes saisies à la main (« images recompressées ») : tout est daté, rappelé à côté
des résultats (« depuis le contrôle précédent : LiteSpeed Cache mis à jour… ») et marqué d'un
losange sur les courbes. Les hooks de WordPress donnent l'heure exacte ; une photographie du site
prise à chaque contrôle rattrape ce qu'ils ne voient pas (fichiers remplacés par FTP, réglages).

**Pistes en langage clair**

Chaque piste de Lighthouse reçoit une explication rédigée à la main (pas d'IA), et, si LiteSpeed
Cache ou ShortPixel sont actifs, l'endroit où regarder dans ces extensions. Une piste apparue
depuis le contrôle précédent est marquée « New ». Les ressources en cause (images trop lourdes…)
sont listées.

Diagnostics propres à la pile LiteSpeed, en lecture seule :

* repères de LiteSpeed Cache lus dans le HTML servi : date de mise en cache, présence du Critical
  CSS et du CSS unique ;
* LCP au-dessus de 4 s sans Critical CSS alors que le chargement asynchrone du CSS est actif :
  Critical CSS probablement non régénéré ;
* CLS qui dépasse 0,25 avec CSS Combine actif : rappel de vérifier la mise en page ;
* QUIC.cloud absent alors qu'il répondait au contrôle précédent ;
* mise à jour de LiteSpeed Cache : rappel des vérifications habituelles.

**Search Console : qu'est-ce qu'on gagne ?**

Si une propriété Search Console est choisie, les clics, impressions et positions de chaque page
de référence et du site entier sont importés par jour et par appareil (16 mois au premier
passage). Chaque page affiche les clics hebdomadaires avec le score médian de la semaine.

Le sélecteur « Before / after » compare, autour d'un changement ou d'une note, jusqu'à 28 jours
de part et d'autre : score et LCP médians, clics, impressions et position de la page, et clics du
site entier, qui sert de témoin contre la saisonnalité et les mises à jour de Google. C'est une
corrélation, pas une preuve, et l'écran le dit.

**Export CSV**

Une ligne par contrôle : métriques, données des vrais visiteurs, et chiffres Search Console de la
page ce jour-là pour cet appareil.

**Contrôles**

* Automatiques, chaque jour ou chaque semaine à l'heure choisie (WP-Cron).
* Manuels, depuis le bouton « Run a check now » : la progression s'affiche, l'administration
  reste utilisable, et si l'on quitte la page, WP-Cron termine le contrôle. Un contrôle manuel
  au plus toutes les 5 minutes.

Chaque étape (une page, un appareil) tient en une requête d'une minute au plus : pas de risque
de dépasser la limite d'exécution PHP de l'hébergeur.

**Rien sur le site public**

Hors administration et tâches planifiées, l'extension ne charge rien : ni classe, ni hook, ni
script, ni feuille de style. Lighthouse tourne sur les serveurs de Google ; le serveur du site
ne fait qu'une ou deux requêtes vers la page contrôlée, pour chauffer son cache.

L'extension ne modifie aucun réglage d'une autre extension (LiteSpeed Cache, QUIC.cloud,
ShortPixel…) : elle constate et oriente, elle ne corrige rien.

== Installation ==

1. Téléverser `hkc-performance.zip` depuis Extensions › Ajouter › Téléverser une extension.
2. Activer l'extension.
3. Ouvrir le menu « Performance », cliquer sur « Connect Google », puis « Sign in with Google ».

La page est réservée aux administrateurs (capacité `manage_options`).

== Connexion Google ==

Un bouton « Sign in with Google », une fenêtre popup, un compte Google : rien à configurer.

La connexion passe par **auth.hervekabla.com**, le service de connexion des extensions HKC, qui
détient l'application Google (comme MonsterInsights ou Site Kit). Le parcours :

1. la popup ouvre une page du service qui affiche le site demandeur, à confirmer ;
2. Google affiche son écran de consentement (lecture seule de Search Console) ;
3. le service renvoie vers le site un code à usage unique, valable 5 minutes ;
4. le site échange ce code, serveur à serveur, contre les jetons, avec un vérificateur (PKCE)
   qui n'a jamais quitté le site : un code intercepté ne sert à rien.

Ensuite, **les jetons restent chiffrés sur le site**, et les appels à PageSpeed Insights et à
Search Console partent du site directement vers Google. Le service n'intervient plus que pour
renouveler le jeton d'accès (environ une fois par heure d'utilisation) et pour l'historique
hebdomadaire Chrome UX Report, dont l'API n'accepte pas la connexion Google et passe donc par la
clé du service. Il ne conserve aucun jeton et ne voit passer aucun rapport.

Si le service est momentanément injoignable, le tableau de bord continue d'afficher les derniers
résultats ; les contrôles reprennent dès son retour.

Dans la modale, choisir ensuite la propriété Search Console (celle du site est présélectionnée).

Le parcours prévient la page d'origine par deux canaux (`window.opener` et `BroadcastChannel`),
parce que la politique COOP des pages Google peut couper le premier. Si le navigateur bloque la
popup, le même parcours a lieu dans la fenêtre courante.

**Sans intermédiaire (option avancée)** : un site peut utiliser son propre client OAuth, créé dans
son projet Google Cloud (environ 5 minutes, une fois). La modale guide la création : activer
« PageSpeed Insights API » et « Google Search Console API », audience « Internal » pour un compte
Google Workspace ou « External » publiée « In production » (en « Testing », Google coupe la
connexion tous les 7 jours), client « Web application » avec l'URI de redirection affichée. Une clé
API Chrome UX Report, facultative, ajoute alors l'historique hebdomadaire.

Pour tester un autre relais, définir `HKC_PERFORMANCE_RELAY` dans `wp-config.php`.

== Mises à jour ==

L'extension n'est pas distribuée par wordpress.org : ses mises à jour viennent de
plugins.hervekabla.com (en-tête `Update URI`, mécanisme natif de WordPress 5.8 et suivants).
Elles apparaissent dans l'écran des extensions comme les autres.

== Sécurité ==

* Le jeton de rafraîchissement, et le cas échéant le secret client et la clé CrUX, sont chiffrés
  en base (AES-256-GCM, clé dérivée des sels de `wp-config.php`) et jamais renvoyés au navigateur.
* Le parcours est protégé par un paramètre `state` lié à l'utilisateur et par PKCE ; via le
  service de connexion, par une page de confirmation qui affiche le site demandeur.
* Accès en lecture seule à Search Console.
* Seule l'adresse publique de la page contrôlée est envoyée à Google.

== Stockage ==

Trois tables dédiées — contrôles (`{préfixe}_hkc_performance_checks`), changements du site
(`_events`) et chiffres Search Console (`_search`) — purgées chaque jour au-delà de la durée de
conservation choisie (16 mois par défaut, comme l'historique de Search Console). Seule la capture
d'écran du dernier contrôle de chaque page est conservée.

La désinstallation révoque l'accès chez Google, supprime les tables, les réglages, les jetons,
les alertes masquées et les tâches planifiées.

== Frequently Asked Questions ==

= Les contrôles automatiques partent en retard =

WP-Cron ne s'exécute que lorsqu'une requête atteint PHP. Sur un site dont les pages sont servies
depuis un cache, cela peut tarder. Désactiver WP-Cron (`define( 'DISABLE_WP_CRON', true );`) et
programmer chez l'hébergeur une tâche cron qui appelle `wp-cron.php` toutes les 5 à 15 minutes.

= Combien de requêtes Google ? =

Pages × 2 appareils × passages : avec 5 pages et 3 passages, 30 requêtes par contrôle. Le quota
gratuit de PageSpeed Insights est de 25 000 requêtes par jour.

== Changelog ==

= 0.3.0 =
* Connexion Google en un clic via le service de connexion des extensions HKC (auth.hervekabla.com) : plus rien à créer dans Google Cloud. Les jetons restent sur le site.
* Historique hebdomadaire Chrome UX Report sans clé API.
* Le client OAuth propre au site devient une option avancée.
* Mises à jour automatiques depuis plugins.hervekabla.com.

= 0.2.0 =
* Alertes : seuils réglables sur mobile, chute mesurée contre la semaine précédente, bandeau dans l'administration, compteur sur le menu, email limité à un par 24 heures.
* Journal des changements du site (mises à jour, activations, réglages LiteSpeed Cache) et notes manuelles, rappelés à côté des résultats et marqués sur les courbes.
* Pistes reformulées en langage clair, avec des indications propres à LiteSpeed Cache et ShortPixel ; pistes nouvelles signalées ; ressources en cause listées.
* Diagnostics LiteSpeed : repères de cache et de Critical CSS lus dans la page, Critical CSS manquant, CSS Combine, QUIC.cloud disparu.
* Search Console : import des clics, impressions et positions par jour et par appareil, graphique hebdomadaire, comparaison avant / après contre le site entier.
* Élément LCP affiché.
* Export CSV.

= 0.1.0 =
* Phase 1 : connexion Google en popup (OAuth, client propre au site), contrôles PageSpeed Insights
  mobile et ordinateur avec médiane de plusieurs passages, préchauffage du cache et relevé des
  en-têtes, données terrain Chrome UX Report, historique du score avec marquage des versions de
  Lighthouse, pistes d'amélioration, suggestions de pages depuis Search Console, historique CrUX
  hebdomadaire facultatif.
