MAISON CODE .
/ UX · State Machines · XState · React · Animation

Micro-interactions : ingénierie de l'expérience subconsciente

Pourquoi les meilleures applications semblent « vivantes ». Un guide technique sur les animations à 60 ips, la logique XState, les mises à jour optimistes et la psychologie du feedback.

AB
Alex B.
Micro-interactions : ingénierie de l'expérience subconsciente

Les grosses animations vendent la marque. Les micro-interactions vendent le produit.

Dans le secteur du luxe, la différence entre un sac à 500 € et un sac à 5 000 € se situe souvent au niveau des coutures. En logiciel, la différence entre un SaaS générique et une plateforme premium réside dans les micro-interactions. La façon dont un bouton s’enfonce lorsqu’on clique dessus. La façon dont un élément de liste glisse lorsqu’il est supprimé. Le retour tactile d’un interrupteur à bascule.

Ce ne sont pas des « ravisseurs ». Ce sont des exigences fonctionnelles de qualité perçue. Une interface utilisateur dépourvue de physique et de feedback semble « morte ». Cela ressemble à un PDF.

Chez Maison Code Paris, nous sommes obsédés par ces millisecondes. Nous ne construisons pas seulement des logiciels qui fonctionnent ; nous construisons des logiciels qui semblent inévitables. Il s’agit cependant d’une ingénierie trompeusement difficile.

Pourquoi Maison Code en parle

Chez Maison Code Paris, nous agissons comme la conscience architecturale de nos clients. Nous héritons souvent de stacks “modernes” construites sans compréhension fondamentale de l’échelle.

Nous abordons ce sujet car il représente un point de pivot critique dans la maturité de l’ingénierie. Une mise en œuvre correcte différencie un MVP fragile d’une plateforme résiliente de niveau entreprise.

Pourquoi Maison Code discute des micro-interactions

La plupart des développeurs traitent les animations après coup, en saupoudrant quelques transitions CSS à la fin d’un sprint. Cela conduit à des “jank” (images perdues) et à des “états impossibles” (boutons bloqués lors du chargement). Nous abordons les micro-interactions comme une discipline d’ingénierie fondamentale, combinant les machines à états pour la logique avec l’accélération matérielle pour le rendu.

La physique des objets numériques

Dans le monde réel, rien ne bouge de manière linéaire. Si vous lancez une balle, elle accélère et décélère. Il a une masse. Dans le développement Web, la transition par défaut est « linéaire ». Cela semble robotique et bon marché.

Physique du printemps et courbes d’assouplissement

L’assouplissement CSS standard (« ease-in-out ») est meilleur que linéaire, mais il est toujours basé sur le temps. Il stipule qu’une animation doit prendre 300 ms. Spring Physics, utilisé dans iOS/Android natif, simule la tension et la friction. Si une animation est interrompue (par exemple, l’utilisateur annule un glissement), un ressort gère naturellement le transfert de vitesse. Une courbe standard se casserait ou se réinitialiserait maladroitement.

Pour le Web, nous utilisons Framer Motion ou React Spring pour utiliser des moteurs physiques fiables.

// La sensation "Leica Click"
importer { motion } depuis 'framer-motion' ;

const PrimaryButton = ({ enfants, onClick }) => (
  <motion.bouton
    whileHover={{ échelle : 1,02 }}
    whileTap={{ échelle : 0,95 }}
    transition={{ type : "ressort", rigidité : 400, amortissement : 17 }}
    onClick={onClick}
    nom de classe = "btn-primaire"
  >
    {enfants}
  </motion.button>
);

Ce code simple ajoute de la masse au bouton. Il semble « lourd » et substantiel, approprié pour les actions de grande valeur telles que « Commander » ou « Publier ».

Les performances de rendu : atteindre 60 FPS

Le « Gold Standard » pour l’animation de l’interface utilisateur est un 60 images par seconde (FPS) cohérent. Cela donne au navigateur 16,6 ms pour restituer chaque image. Pour y parvenir, vous devez uniquement animer les propriétés qui ne déclenchent pas les cycles Layout ou Paint du navigateur. Vous devez rester sur le Thème du compositeur.

Les propriétés bon marché

  • transformer (traduire, mettre à l’échelle, faire pivoter)
  • opacité

Les propriétés chères (à éviter)

  • largeur / hauteur
  • haut / gauche / marge
  • box-shadow (parfois)

Exemple de mise en page

Si vous animez la « hauteur » d’un accordéon pour l’ouvrir, le navigateur doit recalculer la position de chaque élément en dessous sur chaque image. Cela provoque des parasites sur les appareils mobiles. Solution : La technique “Scale Inverse”.

  1. Rendre l’élément en taille réelle mais masqué.
  2. Utilisez transform: scaleY pour animer son ouverture.
  3. Échellez les enfants pour qu’ils n’aient pas l’air écrasés.
  4. Ou plus simple : utilisez l’accessoire “layout” de framer-motion, qui gère automatiquement les calculs FLIP (First Last Invert Play).

Logique : La machine à états (XState)

Une animation fluide est inutile si la logique qui la sous-tend est brisée. Le bug le plus courant dans le développement frontend est « l’explosion booléenne ».

// Mauvaise pratique
const [isLoading, setIsLoading] = useState(false);
const [isSuccess, setIsSuccess] = useState(false);
const [isError, setIsError] = useState(false);

Que se passe-t-il si « isLoading » et « isError » sont tous deux « vrais » ? Vous avez une double flèche et un message d’erreur qui se chevauchent. Il s’agit d’un état impossible.

Nous utilisons des Finite State Machines (FSM) via XState pour garantir mathématiquement la validité. Un bouton ne peut être que dans un seul état à la fois.

importer { createMachine } depuis 'xstate' ;

exporter const boutonMachine = createMachine({
  identifiant : 'bouton',
  initiale : 'inactif',
  déclare : {
    inactif : { activé : { CLIQUEZ : 'chargement' } },
    chargement : {
      invoquer : {
        src : 'soumettreFormulaire',
        onDone : 'succès',
        onError : 'erreur'
      }
    },
    succès : { 
        après : { 2000 : 'inactif' } // Réinitialisation automatique
    },
    erreur : { sur : { RÉESSAYER : 'chargement' } }
  }
});

Lorsque vous connectez cela à votre interface utilisateur, vous arrêtez de vérifier « if (isLoading && !isError) ». Vous effectuez simplement un rendu basé sur « state.value ». Cette robustesse rend la micro-interaction solide et sans bug.

Optimistic UI : L’illusion de la vitesse

Les micro-interactions sont responsables de la performance perçue. La technique la plus puissante est la Mise à jour optimiste. Lorsqu’un utilisateur « aime » une publication, nous n’attendons pas la confirmation du serveur. Nous teignons le cœur en rouge immédiatement. Nous envoyons ensuite la demande en arrière-plan.

  • Succès : Ne rien faire (l’interface utilisateur est déjà correcte).
  • Échec : restaurez l’interface utilisateur (devenez gris en forme de cœur) et affichez une erreur de toast.

Cela donne à l’application une sensation Local-First, supprimant ainsi la latence du réseau de la boucle d’interaction.

// Mise à jour optimiste de la requête React
const { muter } = useMutation ({
  mutationFn : likePost,
  onMutate : async (postId) => {
    wait queryClient.cancelQueries(['post', postId]);
    const previousPost = queryClient.getQueryData(['post', postId]);

    // Mettre à jour avec optimisme
    queryClient.setQueryData(['post', postId], (old) => ({
      ... vieux,
      isLiked : vrai,
      j'aime : vieux.j'aime + 1,
    }));

    return {post précédent } ;
  },
  onError : (erreur, postId, contexte) => {
    // Rollback sur erreur
    queryClient.setQueryData(['post', postId], context.previousPost);
  },
});

Psychologie : boucles de rétroaction et attente

La règle des 100 ms

  • < 100 ms : instantané. L’utilisateur a le sentiment d’avoir directement provoqué l’action.
  • 100 ms - 300 ms : La machine fonctionne.
  • > 1000 ms : L’esprit de l’utilisateur s’égare.

Détails artificiels

Parfois, les ordinateurs sont trop rapides. Si vous cliquez sur « Vérifier le pointage de crédit » et qu’il revient dans 50 ms, l’utilisateur fait moins confiance au résultat. “Il n’a pas réellement vérifié ; il a juste deviné.” Pour les opérations de grande valeur (paiements, contrôles de sécurité), nous injectons un délai artificiel (par exemple, 800 ms - 1,5 s) avec une animation complexe (« Contacter la banque… », « Jeton de vérification… »). Ce « Théâtre de sécurité » renforce la confiance.

Haptique et son

Les visuels ne sont qu’un sens. Des micro-interactions détaillées engagent le toucher et l’audition.

Retour haptique

Sur mobile, le doigt masque le bouton. Utilisez l’API Vibration pour confirmer.

  • navigator.vibrate(10) : coche subtile (accrochage du curseur).
  • navigator.vibrate([50, 20, 50]) : Erreur / Avertissement.

Conception sonore

Les “UI Sounds” sont dangereux s’ils sont mal faits, mais magiques s’ils sont bien faits (pensez au “Click” de la Nintendo Switch).

  • Fréquence : les sons à haute fréquence semblent « légers » et « précis ». Les basses fréquences semblent « lourdes » et « avertissantes ».
  • Volume : doit être à peine audible.
  • Contexte : ne jouez jamais de son lors de simples chargements de page. Uniquement sur les actions initiées par l’utilisateur (Succès, Supprimer).

Accessibilité

Les micro-interactions ne doivent pas exclure les utilisateurs.

  • Troubles vestibulaires : certains utilisateurs souffrent du mal des transports à cause de la parallaxe ou des grandes animations de zoom.
    • Exigence : Respecter « préfère les mouvements réduits ».
    • Implémentation : désactivez les animations génériques ou passez à de simples fondus d’opacité.
  • Lecteurs d’écran : le lecteur d’écran sait-il que le bouton est « Chargement » ?
    • Utilisez les régions aria-live="polite" pour annoncer les changements de statut sans changer de focus.
@media (préfère le mouvement réduit : réduire) {
  * {
durée de l'animation : 0,01 ms !important ;
durée de transition : 0,01 ms !important ;
}
}

Conclusion

Les micro-interactions sont le ciment qui maintient l’interface utilisateur ensemble. Ils communiquent l’état, évitent les erreurs via un retour d’information clair et créent un sentiment de manipulation directe. En B2B Haut de Gamme et B2C Luxe, ces interactions communiquent la compétence de la marque.

Si vous les ignorez, vous disposez d’une interface de base de données fonctionnelle. Si vous les maîtrisez, vous disposez d’un produit numérique.


Élevez votre UX

Votre application semble rigide ou ne répond pas ?

Engagez nos Architectes.