Files
Portfolio-Codex/docs/stories/3.6.optimisation-images.md

5.7 KiB

Story 3.6: Optimisation des Images Projets

Status

Ready for Dev

Story

As a visiteur, I want que les images des projets se chargent rapidement, so that je n'attends pas et j'ai une expérience fluide.

Acceptance Criteria

  1. Les images sont stockées dans assets/img/projects/
  2. Le lazy loading est activé sur toutes les images (attribut loading="lazy")
  3. Les images ont des dimensions explicites (width/height) pour éviter le layout shift
  4. Le format WebP est utilisé avec fallback JPG/PNG via <picture>
  5. Les thumbnails sont redimensionnés (max 400px de large)
  6. Le score Lighthouse "Images" est vert (>90)

Tasks / Subtasks

  • [] Task 1 : Organiser le dossier images (AC: 1)

    • [] Créer assets/img/projects/
    • [] Définir la convention de nommage : {slug}-{type}.{ext}
    • [] Exemple : ecommerce-xyz-thumb.webp, ecommerce-xyz-screen-1.webp
  • [] Task 2 : Implémenter le lazy loading (AC: 2)

    • [] Ajouter loading="lazy" sur toutes les images projets
    • [] Image principale above-the-fold sans lazy loading (false)
  • [] Task 3 : Ajouter les dimensions explicites (AC: 3)

    • [] Définir les tailles standards : thumbnail (400x225), screenshot (800x450), hero (1200x675)
    • [] Ajouter width et height sur toutes les <img>
  • [] Task 4 : Implémenter WebP avec fallback (AC: 4)

    • [] Utiliser <picture> avec <source type="image/webp">
    • [] Fallback vers JPG
  • [] Task 5 : Documenter les tailles recommandées (AC: 5)

    • [] Thumbnails : 400x225, qualité 80%
    • [] Screenshots : 800x450, qualité 85%
    • [] Hero : 1200x675, qualité 85%
    • [] Documentation dans Dev Notes
  • Task 6 : Tester les performances (AC: 6)

    • Audit Lighthouse sur la page projets (requiert images réelles)
    • Vérifier le score images > 90
    • Vérifier le CLS < 0.1

Dev Notes

Convention de Nommage des Images

assets/img/projects/
├── ecommerce-xyz-thumb.webp      # Thumbnail (400x225)
├── ecommerce-xyz-thumb.jpg       # Fallback JPG
├── ecommerce-xyz-screen-1.webp   # Screenshot 1 (800x450)
├── ecommerce-xyz-screen-1.jpg    # Fallback
├── ecommerce-xyz-screen-2.webp   # Screenshot 2
├── app-gestion-thumb.webp
├── app-gestion-screen-1.webp
└── default-project.webp          # Image par défaut

Format : {slug}-{type}.{extension}

Type Usage Dimensions Qualité
thumb Carte projet 400x225 (16:9) 80%
screen-N Captures d'écran 800x450 (16:9) 85%
hero Image principale 1200x675 (16:9) 85%

Template Image avec Picture

<?php
/**
 * Helper pour afficher une image optimisée
 */
function projectImage(string $filename, string $alt, int $width, int $height, bool $lazy = true): string
{
    $webp = $filename;
    $fallback = str_replace('.webp', '.jpg', $filename);
    $lazyAttr = $lazy ? 'loading="lazy"' : '';

    return <<<HTML
<picture>
    <source srcset="/assets/img/projects/{$webp}" type="image/webp">
    <img
        src="/assets/img/projects/{$fallback}"
        alt="{$alt}"
        width="{$width}"
        height="{$height}"
        {$lazyAttr}
        class="w-full h-full object-cover"
    >
</picture>
HTML;
}

Usage dans les Templates

<!-- Dans project-card.php -->
<div class="aspect-thumbnail overflow-hidden">
    <?= projectImage(
        $project['thumbnail'],
        "Aperçu du projet " . $project['title'],
        400,
        225,
        true // lazy loading
    ) ?>
</div>

Checklist Optimisation Image

Pour chaque image :

  • Format WebP créé
  • Fallback JPG créé
  • Redimensionnée à la taille cible
  • Compressée (qualité 80-85%)
  • Nommée selon la convention

Outils Recommandés

Outil Usage
Squoosh.app Compression web (gratuit)
ImageMagick CLI batch conversion
Sharp (Node) Automatisation build

Commandes ImageMagick

# Convertir en WebP
convert input.jpg -quality 80 -resize 400x225 output.webp

# Batch conversion
for f in *.jpg; do
    convert "$f" -quality 80 "${f%.jpg}.webp"
done

Métriques de Performance Cibles

Métrique Objectif
Lighthouse Images > 90
CLS < 0.1
LCP (si image above-fold) < 2.5s
Taille thumbnail < 30kb
Taille screenshot < 80kb

Testing

  • [] Toutes les images sont dans assets/img/projects/
  • [] Le lazy loading fonctionne (attribut loading="lazy")
  • [] Dimensions explicites pour éviter CLS (width/height)
  • [] Les images WebP sont servies via <picture>
  • [] Le fallback JPG est présent dans <img src>
  • Score Lighthouse images > 90 (requiert images réelles)

Dev Agent Record

Agent Model Used

Claude Opus 4.5 (claude-opus-4-5-20251101)

File List

File Action Description
includes/functions.php Modified Ajout fonction projectImage()
templates/project-card.php Modified Utilise projectImage()
pages/project-single.php Modified Utilise projectImage() pour hero et galerie

Completion Notes

  • Fonction projectImage() créée avec support <picture> WebP + fallback JPG
  • Tailles standards définies: thumbnail (400x225), screenshot (800x450), hero (1200x675)
  • Lazy loading activé par défaut, désactivé pour images above-the-fold
  • Fallback onerror vers default-project.svg
  • Templates mis à jour: project-card.php, project-single.php
  • Task 6 (Lighthouse) non testable sans images réelles

Debug Log References

Aucun problème rencontré.

Change Log

Date Version Description Author
2026-01-22 0.1 Création initiale Sarah (PO)
2026-01-23 1.0 Implémentation complète James (Dev)