Optimisation du chargement des images avec les composants React Spectrum Image et Avatar

Composants d'image React Spectrum : stratégies d'optimisation

Les performances de chargement des images influencent directement l'expérience utilisateur et les Core Web Vitals dans les applications web modernes. React Spectrum, la bibliothèque de composants UI open source d'Adobe, propose des composants Image et Avatar professionnels intégrant diverses stratégies d'optimisation.

Caractéristiques principales du composant Image

Utilisation de base

import { Image } from '@react-spectrum/image';

function IllustrationProduit({ produit }) {
  return (
    <Image
      src={produit.urlImage}
      alt={produit.nom}
      objectFit="cover"
      onLoad={(e) => console.log('Image chargée:', e.target)}
      onError={(e) => console.error('Échec du chargement:', e.target)}
      crossOrigin="anonymous"
    />
  );
}

Propriétés principales

Propriété Type Description
src string URL de l'image avec support des images responsives
alt string Texte alternatif pour l'accessibilité et le SEO
objectFit string Mode de remplissage de l'image
onLoad function Callback de fin de chargement
onError function Calllback d'erreur de chargement
crossOrigin string Configuraton CORS pour CDN et cache

Optimisation du composant Avatar

Implémentation standard

import { Avatar } from '@react-spectrum/avatar';

function ProfilUtilisateur({ utilisateur }) {
  return (
    <Avatar
      src={utilisateur.urlAvatar}
      alt={utilisateur.nom}
      size="avatar-size-300"
      isDisabled={!utilisateur.estActif}
    />
  );
}

Dimensions standards

Constante Valeur Usage
avatar-size-50 16px Icônes minuscules
avatar-size-100 32px Dimension par défaut
avatar-size-300 64px Pages de profil
avatar-size-500 128px Affichages larges

Techniques d'optimisation avancées

Stratégie de chargement responsive

function ImageOptimisee({ image }) {
  const [estChargee, setEstChargee] = useState(false);
  const [aErreur, setAErreur] = useState(false);

  const gestionChargement = useCallback(() => {
    setEstChargee(true);
    performance.mark('image-chargee');
  }, []);

  const gestionErreur = useCallback(() => {
    setAErreur(true);
  }, []);

  return (
    <div className={`conteneur-image ${estChargee ? 'chargee' : 'chargement'}`}>
      {!estChargee && !aErreur && (
        <div className="squelette-image">
          {/* Placeholder skeleton */}
        </div>
      )}
      <Image
        src={image.src}
        srcSet={`${image.src}?largeur=400 400w, ${image.src}?largeur=800 800w`}
        sizes="(max-width: 600px) 400px, 800px"
        alt={image.alt}
        onLoad={gestionChargement}
        onError={gestionErreur}
        objectFit="cover"
      />
    </div>
  );
}

Implémentation du lazy loading

import { useInView } from 'react-intersection-observer';

function ImageDifferee({ src, alt, ...props }) {
  const [ref, enVue] = useInView({
    threshold: 0.1,
    triggerOnce: true,
  });

  return (
    <div ref={ref}>
      {enVue ? (
        <Image
          src={src}
          alt={alt}
          {...props}
        />
      ) : (
        <div className="placeholder-image">
          {/* Image de faible qualité (LQIP) */}
        </div>
      )}
    </div>
  );
}

Gestion des erreurs et fallback

function AvatarResilient({ utilisateur, ...props }) {
  const [srcActuel, setSrcActuel] = useState(utilisateur.urlAvatar);
  const [tentatives, setTentatives] = useState(0);

  const gestionErreur = useCallback(() => {
    if (tentatives < 2) {
      setTentatives(prev => prev + 1);
      setSrcActuel(`${utilisateur.urlAvatar}?retry=${tentatives + 1}`);
    } else {
      setSrcActuel('/avatar-par-defaut.png');
    }
  }, [tentatives, utilisateur.urlAvatar]);

  return (
    <Avatar
      src={srcActuel}
      alt={utilisateur.nom}
      onError={gestionErreur}
      {...props}
    />
  );
}

Surveillance des performances

Mesure des indicateurs clés

function usePerformancesImage(src) {
  const [metriques, setMetriques] = useState({
    tempsChargement: 0,
    tempsDebut: 0,
    estCache: false
  });

  useEffect(() => {
    const debut = performance.now();
    setMetriques(prev => ({ ...prev, tempsDebut: debut }));

    const img = new Image();
    img.onload = () => {
      const tempsChargement = performance.now() - debut;
      const estCache = tempsChargement < 50;
      
      setMetriques({
        tempsChargement,
        tempsDebut: debut,
        estCache
      });

      envoyerMetriquesAnalytics({
        urlImage: src,
        tempsChargement,
        estCache
      });
    };
    img.src = src;

    return () => {
      img.onload = null;
    };
  }, [src]);

  return metriques;
}

Bonnes pratiques de codage

Exemples recommmandés et à éviter

// ✅ Pratique recommandée
const BonneImage = () => (
  <Image
    src="https://exemple.com/image.jpg?largeur=400"
    srcSet="https://exemple.com/image.jpg?largeur=400 400w, https://exemple.com/image.jpg?largeur=800 800w"
    sizes="(max-width: 600px) 400px, 800px"
    alt="Description précise"
    onLoad={gestionChargement}
    onError={gestionErreur}
  />
);

// ❌ Pratique à éviter
const MauvaiseImage = () => (
  <Image
    src="https://exemple.com/image-non-optimisee.jpg"
    alt=""
  />
);

Étiquettes: React Spectrum image Avatar optimisation performance lazy loading

Publié le 19 août à 05h49