Front-end angularforall.com

- Angular gzip Brotli : compression HTTP complète

Compression Gzip Brotli Performance Nginx Angular
Angular gzip Brotli : compression HTTP complète

Configurez gzip et Brotli pour Angular 17+ : Nginx, Apache, angular.json, HttpClient et mesures de performance réelles.

Pourquoi la compression HTTP est essentielle pour Angular

Angular 17+ génère des bundles JavaScript optimisés grâce au tree-shaking et au lazy loading. Mais même optimisé, un bundle de production peut peser plusieurs centaines de kilooctets. Sans compression HTTP, chaque utilisateur télécharge ces fichiers bruts — ce qui pénalise directement le temps de chargement et les Core Web Vitals.

La compression HTTP est la technique la plus efficace pour réduire le poids des transferts réseau. Le serveur compresse les fichiers texte (JS, CSS, HTML, JSON, SVG) avant de les envoyer, et le navigateur les décompresse automatiquement. L'utilisateur ne voit aucune différence — seulement une page qui charge beaucoup plus vite.

Tailles typiques d'un bundle Angular 17+ sans compression

Fichier Taille brute Avec gzip Avec Brotli Gain Brotli
main.[hash].js 480 KB 148 KB 118 KB -75%
polyfills.[hash].js 34 KB 11 KB 9 KB -74%
styles.[hash].css 92 KB 18 KB 14 KB -85%
chunk.[hash].js (lazy) 120 KB 38 KB 30 KB -75%
Total initial 606 KB 177 KB 141 KB -77%

Impact sur les Core Web Vitals

La compression réduit directement le temps de téléchargement des ressources bloquantes, ce qui impacte trois métriques Google Lighthouse :

  • FCP (First Contentful Paint) : le premier contenu visible apparaît plus tôt car les CSS et les chunks initiaux sont plus légers.
  • LCP (Largest Contentful Paint) : le chargement du bundle principal main.js détermine souvent l'hydratation de l'app. Moins de KB = LCP plus rapide.
  • TTFB (Time To First Byte) : la compression réduit la charge réseau du serveur, ce qui peut améliorer le TTFB sur les connexions lentes.
À retenir : Lighthouse note "Enable text compression" comme opportunité critique si aucune compression n'est détectée. Ce point peut valoir jusqu'à 30 points de score Performance.

Sur une connexion 4G standard (20 Mbps), passer de 606 KB à 141 KB réduit le temps de téléchargement des assets initiaux d'environ 1.8 secondes à 0.4 secondes. Sur mobile 3G (5 Mbps), la différence est encore plus marquée.

Comment fonctionne gzip

gzip est basé sur l'algorithme DEFLATE, une combinaison de LZ77 (compression par substitution de chaînes répétées) et du codage de Huffman (représentation optimale des symboles fréquents). Il est disponible depuis 1992 et supporté par 100% des navigateurs actuels.

Concrètement, les fichiers JavaScript et CSS contiennent énormément de patterns répétés : noms de variables, mots-clés du langage (function, return, const), espaces, indentation. gzip identifie ces répétitions et les remplace par des références courtes, réduisant dramatiquement le poids du fichier.

Les niveaux de compression gzip (1–9)

Niveau Vitesse Taux de compression Recommandé pour
1 Très rapide Faible Streaming temps réel
4–6 Bon équilibre Bon Production (recommandé)
9 Lent Maximum Pre-compression statique

Headers HTTP gzip : le dialogue navigateur ↔ serveur

La compression HTTP fonctionne via deux headers de négociation entre le navigateur et le serveur :

# Le navigateur annonce les encodages qu'il supporte
# (envoyé automatiquement par tous les navigateurs modernes)
GET /main.abc123.js HTTP/1.1
Host: monapp.com
Accept-Encoding: gzip, deflate, br

# Le serveur répond avec le fichier compressé et l'indique
HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Encoding: gzip
Content-Length: 148432
Vary: Accept-Encoding

# [données binaires compressées gzip]
# Le navigateur décompresse automatiquement avant exécution
Note : Le header Vary: Accept-Encoding est crucial. Il indique aux CDN et proxies de cacher séparément les versions compressée et non compressée du fichier.

Configuration Nginx gzip basique

# /etc/nginx/nginx.conf ou /etc/nginx/conf.d/default.conf
# Activer la compression gzip pour les assets Angular

http {
    # Activer gzip
    gzip on;

    # Niveau de compression : bon équilibre vitesse/taille
    gzip_comp_level 6;

    # Taille minimale du fichier à compresser (évite les petits fichiers)
    gzip_min_length 256;

    # Envoyer le header Vary pour les proxies et CDN
    gzip_vary on;

    # Compresser aussi les requêtes via proxy
    gzip_proxied any;

    # Types MIME à compresser (essentiels pour Angular)
    gzip_types
        text/plain
        text/css
        text/javascript
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/xml+rss
        image/svg+xml
        font/woff
        font/woff2;

    # Désactiver gzip pour IE6 (obsolète mais safe)
    gzip_disable "MSIE [1-6]\.";
}

Brotli : le successeur de gzip

Brotli est un algorithme de compression développé par Google en 2015. Il combine LZ77, le codage de Huffman et la modélisation de contexte de second ordre. Sa force principale pour les assets web : un dictionnaire statique de 120 000+ mots issus des langages HTML, CSS et JavaScript les plus courants. Ce dictionnaire permet à Brotli de reconnaître et compresser des patterns typiques du code source sans les encoder entièrement.

Gains réels de Brotli sur les bundles Angular

Sur les fichiers JavaScript minifiés (typiques d'une app Angular en production), Brotli offre un gain de 15 à 25% supplémentaire par rapport à gzip au même niveau de qualité CPU. Pour les fichiers CSS, le gain atteint souvent 30%.

Condition obligatoire : Brotli (br dans le header Accept-Encoding) ne fonctionne qu'en HTTPS. Les navigateurs refusent de demander Brotli sur HTTP non sécurisé. En production Angular, votre site doit être servi en HTTPS — ce qui est de toute façon requis pour les Service Workers et de nombreuses API modernes.

Support navigateurs Brotli

Navigateur Support Brotli depuis Version minimale
Chrome 2015 v51+
Firefox 2016 v44+
Safari 2017 v11+
Edge 2016 v15+
Opera 2016 v44+
Support global ~97% des utilisateurs actifs (2026)

Configuration Nginx Brotli

Brotli n'est pas inclus dans Nginx par défaut. Il faut le module ngx_brotli, disponible nativement sur la plupart des distributions Linux modernes via le paquet libnginx-mod-http-brotli-filter.

# Installer le module Brotli sur Ubuntu/Debian
sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static

# Sur CentOS/RHEL avec EPEL
sudo yum install nginx-module-brotli
# /etc/nginx/nginx.conf — activer le module Brotli
# (en haut du fichier de config principal)
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

http {
    # -------- Brotli (prioritaire si supporté) --------
    brotli on;

    # Niveau 6 : bon équilibre compression/CPU (max = 11)
    brotli_comp_level 6;

    # Taille minimale pour déclencher la compression
    brotli_min_length 256;

    # Types MIME cibles (identiques à gzip)
    brotli_types
        text/plain
        text/css
        text/javascript
        application/javascript
        application/x-javascript
        application/json
        application/xml
        image/svg+xml
        font/woff
        font/woff2;

    # -------- gzip (fallback pour navigateurs sans Brotli) --------
    gzip on;
    gzip_comp_level 6;
    gzip_min_length 256;
    gzip_vary on;
    gzip_proxied any;
    gzip_types
        text/plain
        text/css
        text/javascript
        application/javascript
        application/json
        application/xml
        image/svg+xml
        font/woff
        font/woff2;
}
Ordre de priorité : Nginx servira automatiquement Brotli aux navigateurs qui l'annoncent dans Accept-Encoding: br, et gzip aux autres. Aucune logique applicative n'est nécessaire côté Angular.

Angular CLI : préparer les assets pour la production

Angular CLI génère des bundles optimisés lors du build de production. Depuis Angular 17, le builder par défaut est esbuild (via application builder), qui produit des fichiers minifiés, tree-shakés et avec hashes de cache. Voici comment configurer le build et la pre-compression.

Commande de build production

# Build optimisé pour la production (Angular 17+)
ng build --configuration=production

# Les fichiers générés dans dist/mon-app/browser/ :
# main.abc12345.js         → Bundle principal (minifié, tree-shaké)
# polyfills.def67890.js    → Polyfills navigateurs
# styles.ghi11223.css      → Styles globaux (inlinés ou séparés)
# chunk.jkl34567.js        → Chunk lazy-loaded (ex: module admin)
# index.html               → HTML avec les tags script/link
# assets/                  → Images, fonts, fichiers statiques

Configuration angular.json pour la production

// angular.json — configuration production complète
{
  "projects": {
    "mon-app": {
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:application",
          "options": {
            // Répertoire de sortie
            "outputPath": "dist/mon-app",
            // Ajouter un hash dans le nom des fichiers (cache busting)
            "outputHashing": "all",
            // Assets à copier tels quels dans le dist
            "assets": [
              { "glob": "**/*", "input": "public" }
            ],
            // Fichier de styles principal
            "styles": ["src/styles.css"],
            // Fichier TypeScript principal
            "scripts": []
          },
          "configurations": {
            "production": {
              // Minification complète (Angular 17+ actif par défaut)
              "optimization": true,
              // Source maps désactivées en prod (sécurité + taille)
              "sourceMap": false,
              // Extraction des CSS dans des fichiers séparés
              "extractLicenses": true,
              // Budgets de taille pour alerter si bundle trop gros
              "budgets": [
                {
                  "type": "initial",
                  // Erreur si le bundle initial dépasse 500KB
                  "maximumError": "500kb",
                  // Avertissement dès 350KB
                  "maximumWarning": "350kb"
                },
                {
                  "type": "anyComponentStyle",
                  // Les styles de composants ne doivent pas dépasser 4KB
                  "maximumError": "4kb"
                }
              ]
            }
          }
        }
      }
    }
  }
}

Pre-compression des assets Angular (recommandé)

La compression à la volée (dynamic) consomme du CPU à chaque requête. La pre-compression statique génère les fichiers .gz et .br une seule fois au moment du déploiement. Nginx les sert directement sans recalcul.

# Installer les outils de pre-compression
npm install -g gzip brotli

# Après le ng build, compresser tous les assets texte
# (à intégrer dans votre pipeline CI/CD)

# Créer les fichiers .gz pour chaque asset
find dist/mon-app/browser -type f \
  \( -name "*.js" -o -name "*.css" -o -name "*.html" -o -name "*.json" -o -name "*.svg" \) \
  -exec gzip -9 -k {} \;

# Créer les fichiers .br avec brotli CLI
find dist/mon-app/browser -type f \
  \( -name "*.js" -o -name "*.css" -o -name "*.html" -o -name "*.json" -o -name "*.svg" \) \
  -exec brotli --quality=11 --keep {} \;

# Résultat : chaque asset a maintenant 3 versions
# main.abc123.js       → original (fallback)
# main.abc123.js.gz    → version gzip
# main.abc123.js.br    → version Brotli (la plus légère)
CI/CD : Ajoutez ces commandes dans votre pipeline GitHub Actions ou GitLab CI après l'étape ng build pour automatiser la pre-compression à chaque déploiement.

Script npm de build + compression

// package.json — script de build complet avec pre-compression
{
  "scripts": {
    // Build standard Angular
    "build": "ng build",
    // Build production seul
    "build:prod": "ng build --configuration=production",
    // Build + pre-compression gzip ET Brotli
    "build:deploy": "ng build --configuration=production && npm run compress",
    // Compresser les assets générés (Unix/Linux/Mac)
    "compress": "find dist/mon-app/browser -type f \\( -name '*.js' -o -name '*.css' -o -name '*.html' \\) -exec gzip -9 -k {} \\; && find dist/mon-app/browser -type f \\( -name '*.js' -o -name '*.css' -o -name '*.html' \\) -exec brotli --quality=11 --keep {} \\;"
  }
}

Configuration Nginx complète (gzip + Brotli)

Voici une configuration Nginx complète et prête pour la production d'une application Angular. Elle gère la pre-compression statique (fichiers .gz et .br), le fallback dynamique, le routing Angular (SPA), et les en-têtes de cache optimaux.

# /etc/nginx/sites-available/mon-app-angular
# Configuration complète pour une app Angular avec gzip + Brotli

# Charger les modules Brotli (si installés séparément)
# load_module modules/ngx_http_brotli_filter_module.so;
# load_module modules/ngx_http_brotli_static_module.so;

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name monapp.com www.monapp.com;

    # Certificats SSL (Let's Encrypt recommandé)
    ssl_certificate     /etc/letsencrypt/live/monapp.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/monapp.com/privkey.pem;

    # Répertoire racine contenant le dist Angular
    root /var/www/mon-app/dist/mon-app/browser;
    index index.html;

    # -------- Compression Brotli dynamique --------
    # (utilisée si le fichier .br pré-compressé n'existe pas)
    brotli on;
    brotli_comp_level 4;
    brotli_min_length 256;
    brotli_types
        text/plain text/css text/javascript
        application/javascript application/json
        application/xml image/svg+xml
        font/woff font/woff2;

    # -------- Compression gzip dynamique (fallback) --------
    gzip on;
    gzip_comp_level 5;
    gzip_min_length 256;
    gzip_vary on;
    gzip_proxied any;
    gzip_types
        text/plain text/css text/javascript
        application/javascript application/json
        application/xml image/svg+xml
        font/woff font/woff2;

    # -------- Servir les fichiers pré-compressés --------
    # Brotli statique : sert main.js.br si disponible + navigateur supporte br
    brotli_static on;

    # gzip statique : sert main.js.gz si disponible + navigateur supporte gzip
    gzip_static on;

    # -------- Cache long terme pour les assets Angular --------
    # Les fichiers Angular ont des hashes dans leur nom (ex: main.abc123.js)
    # → Cache navigateur de 1 an est sûr : le hash change à chaque déploiement
    location ~* \.(js|css|woff|woff2|ico|webp|png|jpg|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        # Autoriser la lecture depuis d'autres origines (CDN, analytics)
        add_header Access-Control-Allow-Origin "*";
    }

    # -------- Cache court pour index.html --------
    # Ne pas mettre en cache l'HTML : il pointe vers les nouveaux hashes
    location = /index.html {
        expires -1;
        add_header Cache-Control "no-store, no-cache, must-revalidate";
    }

    # -------- Routing Angular SPA --------
    # Renvoyer index.html pour toutes les routes inconnues
    # (nécessaire pour le Router Angular)
    location / {
        try_files $uri $uri/ /index.html;
    }

    # -------- Headers de sécurité --------
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header Referrer-Policy "strict-origin-when-cross-origin";
}

# Redirection HTTP → HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name monapp.com www.monapp.com;
    return 301 https://$host$request_uri;
}

Vérifier que la compression fonctionne

# Tester gzip avec curl
curl -H "Accept-Encoding: gzip" -I https://monapp.com/main.abc123.js
# Vérifier dans la réponse :
# Content-Encoding: gzip    ← compression active

# Tester Brotli avec curl
curl -H "Accept-Encoding: br" -I https://monapp.com/main.abc123.js
# Vérifier dans la réponse :
# Content-Encoding: br    ← Brotli actif

# Tester et afficher la taille réelle du transfert
curl -H "Accept-Encoding: br" -o /dev/null -s -w "Taille: %{size_download} bytes\n" \
  https://monapp.com/main.abc123.js
Astuce : Si Nginx ne sert pas les fichiers .br pré-compressés, vérifiez que le module ngx_http_brotli_static_module.so est bien chargé avec nginx -V 2>&1 | grep brotli.

Configuration Apache (alternative)

Si votre hébergement utilise Apache plutôt que Nginx, voici la configuration équivalente. Apache utilise mod_deflate pour gzip et mod_brotli pour Brotli (disponible depuis Apache 2.4.26).

Activer les modules nécessaires

# Activer les modules sur Ubuntu/Debian
sudo a2enmod deflate    # gzip via DEFLATE
sudo a2enmod brotli     # Brotli (Apache 2.4.26+)
sudo a2enmod headers    # Pour ajouter les headers Vary
sudo a2enmod rewrite    # Pour le routing Angular SPA
sudo systemctl restart apache2

Fichier .htaccess complet pour Angular

# .htaccess — à placer dans dist/mon-app/browser/
# Configuration Apache complète pour Angular + compression

# -------- Activer le moteur de réécriture (routing SPA) --------
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    # Ne pas réécrire les fichiers et dossiers existants
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    # Renvoyer vers index.html pour le Router Angular
    RewriteRule ^ index.html [L]
</IfModule>

# -------- Compression Brotli (Apache 2.4.26+) --------
<IfModule mod_brotli.c>
    # Activer Brotli pour les types MIME Angular
    AddOutputFilterByType BROTLI_COMPRESS \
        text/plain \
        text/css \
        text/javascript \
        application/javascript \
        application/x-javascript \
        application/json \
        application/xml \
        image/svg+xml \
        font/woff \
        font/woff2

    # Niveau de compression (1-11, recommandé : 5-6)
    BrotliCompressionQuality 6
</IfModule>

# -------- Compression gzip via mod_deflate (fallback) --------
<IfModule mod_deflate.c>
    # Appliquer la compression DEFLATE (gzip)
    AddOutputFilterByType DEFLATE \
        text/plain \
        text/css \
        text/javascript \
        application/javascript \
        application/x-javascript \
        application/json \
        application/xml \
        image/svg+xml \
        font/woff \
        font/woff2

    # Envoyer le header Vary pour les proxies
    Header append Vary Accept-Encoding

    # Désactiver pour les navigateurs anciens bogués
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</IfModule>

# -------- Cache long terme pour assets Angular --------
<IfModule mod_expires.c>
    ExpiresActive On

    # Assets avec hash : 1 an (immutable)
    ExpiresByType application/javascript "access plus 1 year"
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"

    # HTML : pas de cache (pointe vers les nouveaux hashes)
    ExpiresByType text/html "access plus 0 seconds"
</IfModule>

# -------- Headers de sécurité --------
<IfModule mod_headers.c>
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>
Important : mod_brotli est disponible nativement depuis Apache 2.4.26 (2017). Si votre serveur utilise une version antérieure, mettez Apache à jour ou compilez le module depuis les sources via apt-get install apache2-dev && apxs -cia mod_brotli.c.

Angular HttpClient et headers de compression

Pour les assets statiques (JS, CSS, HTML), la compression est gérée entièrement côté serveur et navigateur — Angular n'intervient pas. En revanche, pour les appels API effectués via HttpClient, il est possible d'optimiser la gestion de la compression et de s'assurer que les réponses JSON volumineuses sont bien compressées.

Le mécanisme automatique du navigateur

Bonne nouvelle : le navigateur ajoute automatiquement Accept-Encoding: gzip, deflate, br à toutes les requêtes XHR/Fetch, y compris celles d'Angular HttpClient. Vous n'avez rien à configurer pour que les réponses API soient décompressées.

// Angular HttpClient : comportement par défaut (correct)
// Le navigateur ajoute automatiquement Accept-Encoding: gzip, deflate, br
// sur toutes les requêtes XHR, y compris celles d'HttpClient

import { HttpClient } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class ApiService {
    private http = inject(HttpClient);

    // Cette requête bénéficie automatiquement de la compression
    // Le JSON reçu est décompressé par le navigateur avant d'arriver ici
    getProducts(): Observable<Product[]> {
        return this.http.get<Product[]>('/api/products');
        // Headers envoyés automatiquement par le navigateur :
        // Accept-Encoding: gzip, deflate, br
        // Accept: application/json, text/plain, */*
    }
}

Interceptor Angular 17 pour forcer la compression sur certaines APIs

Dans certains cas (API externe mal configurée, proxy interne), vous pouvez utiliser un intercepteur pour s'assurer que le header Accept-Encoding est présent et que la requête est optimisée.

// src/app/interceptors/compression.interceptor.ts
// Interceptor fonctionnel Angular 17+ (standalone)

import { HttpInterceptorFn, HttpRequest, HttpHandlerFn } from '@angular/common/http';

export const compressionInterceptor: HttpInterceptorFn = (
    req: HttpRequest<unknown>,
    next: HttpHandlerFn
) => {
    // Cloner la requête pour ajouter les headers (immuabilité HttpClient)
    const compressedReq = req.clone({
        setHeaders: {
            // Demander explicitement Brotli en priorité, puis gzip
            'Accept-Encoding': 'br, gzip, deflate',
        }
    });

    // Note : ce header est normalement géré par le navigateur
    // Utile seulement si vous utilisez HttpClient côté Node.js (SSR Angular)
    return next(compressedReq);
};
// app.config.ts — enregistrer l'intercepteur
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { compressionInterceptor } from './interceptors/compression.interceptor';

export const appConfig: ApplicationConfig = {
    providers: [
        // Fournir HttpClient avec les intercepteurs
        provideHttpClient(
            withInterceptors([compressionInterceptor])
        ),
    ],
};

Tester la compression API avec curl

# Tester qu'une API retourne bien des données compressées

# Test gzip sur une API JSON
curl -H "Accept-Encoding: gzip" -I https://monapp.com/api/products
# Chercher dans la réponse :
# Content-Encoding: gzip
# Content-Length: 3240    ← taille compressée

# Sans compression pour comparaison
curl -I https://monapp.com/api/products
# Content-Length: 18750   ← taille brute (5.8x plus grand)

# Décompresser et afficher le JSON
curl -H "Accept-Encoding: gzip" --compressed https://monapp.com/api/products | jq .

Angular Universal / SSR : configurer la compression côté serveur Node.js

// server.ts — Angular Universal avec compression (SSR)
import express from 'express';
import compression from 'compression';  // npm install compression

const app = express();

// Activer la compression gzip pour toutes les réponses Express
// (Brotli n'est pas inclus dans le middleware 'compression' standard)
app.use(compression({
    // Niveau de compression gzip
    level: 6,
    // Compresser seulement si la réponse dépasse 1KB
    threshold: 1024,
    // Filtrer les types MIME à compresser
    filter: (req, res) => {
        if (req.headers['x-no-compression']) {
            // Respecter le header custom pour désactiver si besoin
            return false;
        }
        // Utiliser le filtre par défaut (text/*, application/json, etc.)
        return compression.filter(req, res);
    }
}));

// ... reste de la configuration Angular Universal SSR
SSR et Brotli : Pour activer Brotli dans Angular Universal (Express), utilisez le package shrink-ray-current à la place de compression. Il supporte gzip et Brotli avec la même API.

Mesurer et optimiser les résultats

Activer la compression ne suffit pas : il faut vérifier qu'elle fonctionne correctement et mesurer l'impact réel sur les performances de votre application Angular. Voici les outils et méthodes à utiliser.

Chrome DevTools : Network Tab

Dans Chrome DevTools (F12), onglet Network, activez la colonne "Size" et "Content" en faisant clic droit sur les en-têtes de colonnes. Vous verrez pour chaque ressource :

  • Taille de transfert (en haut) : poids réel téléchargé après compression
  • Taille de ressource (en bas) : poids original décompressé
// Vérifier la compression dans les DevTools via JavaScript
// (utile pour un debugging rapide en console)

// Analyser les performances de chargement des ressources
performance.getEntriesByType('resource')
    .filter(entry => entry.name.includes('.js'))
    .map(entry => ({
        // Nom du fichier
        file: entry.name.split('/').pop(),
        // Taille encodée (compressée) transférée en KB
        transfertKB: Math.round(entry.encodedBodySize / 1024),
        // Taille réelle (décompressée) en KB
        tailleReelleKB: Math.round(entry.decodedBodySize / 1024),
        // Ratio de compression
        ratio: ((1 - entry.encodedBodySize / entry.decodedBodySize) * 100).toFixed(1) + '%'
    }))
    .forEach(r => console.table(r));
// Exemple de sortie :
// main.abc123.js : 148 KB transféré / 480 KB réel → 69.2% de compression

Lighthouse : audit "Enable text compression"

# Lancer Lighthouse en ligne de commande (nécessite Node.js)
npm install -g lighthouse

# Audit de performance complet
lighthouse https://monapp.com --output html --output-path rapport.html

# Vérifier spécifiquement la compression
lighthouse https://monapp.com --only-audits=uses-text-compression

# Résultat attendu avec compression activée :
# "Enable text compression" → Passed ✓
# Économies potentielles : 0 KB (déjà optimisé)

Angular Bundle Analyzer

# Installer l'analyseur de bundles (optionnel mais très utile)
npm install -g webpack-bundle-analyzer

# Générer les stats Angular (Angular 17+ avec esbuild)
ng build --configuration=production --stats-json

# Analyser visuellement le bundle
webpack-bundle-analyzer dist/mon-app/browser/stats.json

# Alternative : source-map-explorer
npm install -g source-map-explorer
ng build --configuration=production --source-map
source-map-explorer dist/mon-app/browser/main.*.js

Benchmarks avant/après compression

Métrique Sans compression Avec gzip Avec Brotli
Taille totale transfert 606 KB 177 KB (-71%) 141 KB (-77%)
Temps chargement 4G (20 Mbps) ~1.8s ~0.5s ~0.4s
Temps chargement 3G (5 Mbps) ~7.2s ~2.1s ~1.7s
Score Lighthouse Performance ~55 ~82 ~87
LCP (Largest Contentful Paint) ~4.2s ~1.8s ~1.4s

Checklist de déploiement production

  • ng build --configuration=production exécuté (tree-shaking, minification)
  • Pre-compression .gz et .br générée pour tous les assets JS/CSS/HTML
  • Module Nginx ngx_brotli installé et chargé
  • brotli_static on; et gzip_static on; configurés dans Nginx
  • HTTPS actif (obligatoire pour Brotli dans les navigateurs)
  • Header Vary: Accept-Encoding présent dans les réponses
  • Cache long terme activé pour les assets avec hash (Cache-Control: immutable)
  • index.html non mis en cache (no-store)
  • Test curl -H "Accept-Encoding: br" -I confirme Content-Encoding: br
  • Lighthouse "Enable text compression" → Passed ✓
  • Budget Angular configuré dans angular.json (maximumError: 500kb)

Conclusion

La compression HTTP avec gzip et Brotli est l'un des gains de performance les plus rapides et les plus impactants pour une application Angular en production. En quelques lignes de configuration Nginx ou Apache, vous pouvez réduire le poids des transferts de 70 à 77%, ce qui se traduit directement par des scores Lighthouse meilleurs, un LCP plus rapide et une expérience utilisateur améliorée sur mobile et connexions lentes.

La stratégie recommandée est la suivante : utilisez Brotli comme algorithme principal (meilleure compression, supporté par 97% des navigateurs) avec gzip comme fallback, activez la pre-compression statique dans votre pipeline CI/CD pour zéro overhead CPU en production, et configurez le cache long terme sur vos assets Angular grâce au cache busting par hash.

À retenir : Brotli nécessite HTTPS. Activez toujours gzip en parallèle comme fallback. La pre-compression statique (.br + .gz générés au build) est bien plus performante que la compression dynamique à la volée.

Partager