# Le .htaccess gonflé de redirections : le coût invisible à chaque requête

> Des années de redirections 301 accumulées dans .htaccess ralentissent Apache avant même que PHP ne démarre. Comment les migrer vers une table interrogée une seule fois.

- Auteur : Clément Hadrot
- Publié le : 2020-12-05
- Mis à jour le : 2020-12-05
- Catégorie : Performance
- URL : https://wpmoderne.dev.wordpress-developpement.fr/performance/htaccess-gonfle-redirections-cout-invisible/

## L’essentiel

- Chaque règle RewriteRule est évaluée dans l'ordre à chaque requête
- Un .htaccess de plusieurs centaines de lignes coûte un temps mesurable
- Une table de redirections en base élimine ce coût pour les URL non concernées

Un site institutionnel refondu à trois reprises en huit ans traînait un `.htaccess` devenu impressionnant : 340 lignes, dont l'essentiel constitué de redirections 301 accumulées refonte après refonte, jamais nettoyées. Chaque ancienne structure d'URL, chaque ancien système de catégories, chaque campagne marketing terminée depuis longtemps y avait laissé sa trace sous forme de règle `RewriteRule`.

Ce genre de fichier fonctionne, au sens où il ne provoque aucune erreur visible. Mais il a un coût, discret et cumulatif : Apache évalue les règles de réécriture dans l'ordre pour chaque requête entrante, y compris pour les milliers de requêtes qui ne correspondent à aucune redirection.

## Ce que fait réellement Apache à chaque requête

Le module `mod_rewrite` traite les règles de haut en bas, et pour chaque règle, évalue si le motif de l'expression régulière correspond à l'URL demandée. Sur un fichier de quelques lignes, ce traitement est instantané. Sur un fichier de plusieurs centaines de lignes contenant des expressions régulières parfois complexes, le temps cumulé devient mesurable, en particulier sur un serveur déjà chargé.

Un test réalisé avec Apache Bench, en comparant une requête vers une page qui ne correspond à aucune règle de redirection avec le `.htaccess` complet puis avec un `.htaccess` réduit au strict minimum, a montré un écart de plusieurs millisecondes par requête, ce qui, multiplié par le volume de trafic quotidien du site, représentait un temps CPU non négligeable à l'échelle du mois.

## Pourquoi ce n'est pas qu'un problème de style

Au-delà de la performance pure, ce `.htaccess` posait un problème de maintenabilité : personne dans l'équipe ne savait plus avec certitude quelles règles étaient encore utiles. Une tentative de suppression manuelle risquait de casser des liens entrants issus de campagnes publicitaires anciennes encore actives sur des supports imprimés.

> L'essentiel à retenir : Chaque règle RewriteRule est évaluée dans l'ordre à chaque requête ; Un .htaccess de plusieurs centaines de lignes coûte un temps mesurable ; Une table de redirections en base élimine ce coût pour les URL non concernées

## La migration vers une table de redirections

La solution retenue a consisté à extraire l'ensemble des redirections vers une table dédiée en base de données, interrogée une seule fois par requête via un hook `template_redirect`, uniquement lorsque WordPress n'a trouvé aucun contenu correspondant à l'URL demandée :

```
add_action( 'template_redirect', function () {
    if ( ! is_404() ) {
        return;
    }

    global $wpdb;
    $chemin = wp_parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
    $cible  = $wpdb->get_var( $wpdb->prepare(
        "SELECT url_cible FROM {$wpdb->prefix}redirections WHERE url_source = %s",
        $chemin
    ) );

    if ( $cible ) {
        wp_safe_redirect( $cible, 301 );
        exit;
    }
} );
```

Ce mécanisme ne s'exécute que lorsque WordPress a déjà déterminé qu'aucun contenu ne correspond à l'URL, c'est-à-dire uniquement pour les liens cassés potentiels, jamais pour les milliers de requêtes qui touchent des pages existantes. Le coût pour l'immense majorité du trafic redevient nul.

## Vérifier avant de couper l'ancien système

Pendant une période de transition de deux semaines, les deux systèmes ont coexisté : le `.htaccess` restait en place, mais chaque redirection qu'il gérait était dupliquée dans la nouvelle table, avec un compteur d'utilisation incrémenté à chaque déclenchement. Cela a permis d'identifier, sans risque, les règles qui n'avaient plus servi une seule fois en quinze jours.

- Sur 340 lignes initiales, seules 58 redirections ont montré une utilisation réelle pendant la période de test.
- Les règles jamais déclenchées ont été archivées dans un fichier séparé, hors de la table active, plutôt que supprimées définitivement.
- Le `.htaccess` final ne conservait que les règles techniques indispensables, sans logique métier.

## Notre verdict

Un `.htaccess` qui grossit refonte après refonte finit par coûter cher, non pas en une seule fois, mais à chaque requête, indéfiniment. Migrer les redirections métier vers une table interrogée une seule fois, et seulement en cas de contenu introuvable, redonne au fichier Apache son rôle d'origine : de la configuration technique légère, pas un historique de dix ans de décisions marketing.
