12k
All articles

5 APIs JavaScript que tout développeur frontend devrait connaître

5 API JavaScript natives pour les développeurs frontend: IntersectionObserver, ResizeObserver, AbortController, Clipboard API et View Transitions.

OpenReplay Team
OpenReplay Team
5 APIs JavaScript que tout développeur frontend devrait connaître

Les cinq APIs natives du navigateur les plus utiles à maîtriser dès maintenant sont IntersectionObserver, ResizeObserver, AbortController, l’API Clipboard et l’API View Transitions : chacune remplace une dépendance courante par une primitive de la plateforme disponible dans tous les navigateurs actuels.

La plupart d’entre nous l’apprennent à nos dépens : on intègre une bibliothèque entière pour un simple bouton de copie, ou on perd une après-midi sur un champ de recherche qui continue d’afficher des résultats obsolètes, pour découvrir ensuite que le navigateur disposait déjà de la solution. Si vous utilisez déjà fetch, localStorage et le DOM, mais que vous n’avez pas encore exploré les APIs observer et utilitaires plus récentes, voici la liste restreinte qui vous permettra de supprimer une ou deux dépendances. Tout ce qui suit est une API native de la plateforme web, et non un service REST hébergé comme TMDB ou Unsplash : pas de clé, pas de serveur, et aucun coût d’exécution au-delà du navigateur que vous ciblez déjà. Chaque entrée comprend une définition en une ligne, un extrait de code minimal fonctionnel, un cas d’usage concret et une note honnête sur la compatibilité.

Points clés à retenir

  • IntersectionObserver signale quand un élément entre dans le viewport ou en sort, sans listener de scroll, et est disponible sur tous les navigateurs (Baseline) depuis mars 2019.
  • ResizeObserver réagit à la taille de la propre boîte de contenu ou de bordure d’un élément, ce qui rend possibles les composants adaptatifs au conteneur, là où l’événement resize de la fenêtre ne peut rien faire.
  • AbortController est la solution standard aux race conditions dans React : passez controller.signal à fetch et appelez controller.abort() dans le nettoyage de l’effet, afin qu’une réponse obsolète ne puisse pas écraser une interface à jour.
  • navigator.clipboard.writeText() est le remplacement basé sur les promesses du hack document.execCommand('copy'), mais il ne fonctionne que dans un contexte sécurisé (HTTPS ou localhost).
  • Les View Transitions au sein d’un même document ont atteint le statut Baseline Newly available le 14 octobre 2025 et se dégradent gracieusement, ce qui permet de les livrer en production derrière une garde if (document.startViewTransition).

IntersectionObserver : l’API web qui remplace les listeners de scroll

IntersectionObserver signale de manière asynchrone quand un élément cible entre dans le viewport (ou dans un ancêtre quelconque) ou en sort, ce qui vous permet de charger des ressources en différé, de déclencher le défilement infini et de collecter des données d’analyse de visibilité sans un seul listener de scroll. Elle est disponible sur tous les navigateurs depuis mars 2019. Les listeners de scroll se déclenchent des dizaines de fois par seconde sur le thread principal et vous obligent à calculer la géométrie vous-même ; l’observer regroupe ce travail en dehors du chemin critique et ne vous appelle que lorsque la visibilité change réellement.

const observer = new IntersectionObserver((entries) => {
  for (const entry of entries) {
    if (entry.isIntersecting) {
      entry.target.src = entry.target.dataset.src; // load only when visible
      observer.unobserve(entry.target);
    }
  }
});

document.querySelectorAll('img[data-src]').forEach((img) => observer.observe(img));

Ce code charge les images en différé au fur et à mesure que les lignes défilent dans le viewport. La même vérification isIntersecting pilote les sentinelles de défilement infini et les événements d’analyse « vu ». Les replays de session sur des flux longs rendent le bénéfice évident : les images hors écran et les événements de suivi ne se résolvent qu’au moment où leurs lignes entrent dans le viewport, et non toutes à la fois au chargement. Remplace react-intersection-observer et les calculs de scroll manuels dans la plupart des cas. (Remarque : l’option trackVisibility est encore expérimentale et n’est pas Baseline. Restez sur isIntersecting.)

ResizeObserver : réactions aux redimensionnements au niveau de l’élément

Préférez ResizeObserver à l’événement resize de la fenêtre dès qu’un composant doit réagir à sa propre taille : il signale les changements de boîte de contenu et de boîte de bordure au niveau de l’élément, ce qui rend possibles les composants adaptatifs au conteneur. Un handler window.resize vous indique que le viewport a changé ; il ne dit rien d’un panneau qui a rétréci parce qu’une barre latérale s’est ouverte.

const ro = new ResizeObserver((entries) => {
  for (const entry of entries) {
    const { width } = entry.contentRect;
    entry.target.classList.toggle('is-narrow', width < 400);
  }
});

ro.observe(document.querySelector('.card'));

Ici, la carte bascule vers une mise en page compacte en fonction de sa propre largeur : une container query en JavaScript. Il est disponible sur tous les navigateurs actuels et remplace des bibliothèques comme element-resize-detector. Si vous voyez un avertissement ResizeObserver loop dans la console, il est généralement bénin et signifie que vous avez modifié la taille à l’intérieur du callback.

AbortController : annuler les requêtes fetch et corriger les race conditions

AbortController est la solution standard aux race conditions dans React : passez controller.signal à fetch, appelez controller.abort() dans le nettoyage de votre effet, et une réponse obsolète ne pourra jamais écraser une interface à jour après une navigation rapide. AbortSignal est disponible sur tous les navigateurs depuis avril 2018.

useEffect(() => {
  const controller = new AbortController();
  fetch(`/api/results?q=${query}`, { signal: controller.signal })
    .then((res) => res.json())
    .then(setResults)
    .catch((err) => {
      if (err.name !== 'AbortError') throw err;
    });
  return () => controller.abort(); // cancel on unmount or new query
}, [query]);

Le bug classique que cela élimine est celui qu’un replay de session met clairement en évidence : l’utilisateur tape rapidement, une réponse lente antérieure arrive en dernier, et des données obsolètes s’affichent par-dessus la vue actuelle. Annuler la requête en cours lors du nettoyage rend cela impossible. Pour les timeouts spécifiquement, vous pouvez vous passer du controller manuel. AbortSignal.timeout() fonctionne sur tous les navigateurs depuis avril 2024 et annule la requête avec une TimeoutError, tandis qu’une annulation déclenchée par l’utilisateur lève une AbortError, ce qui permet à un seul catch de les distinguer :

fetch(url, { signal: AbortSignal.timeout(5000) });

Remplace les flags isMounted et axios.CancelToken.

API Clipboard : copier dans le presse-papiers sans le hack execCommand

navigator.clipboard.writeText() est le remplacement moderne basé sur les promesses du hack document.execCommand('copy'). Notez simplement qu’il ne fonctionne que dans un contexte sécurisé (HTTPS ou localhost).

copyBtn.addEventListener('click', async () => {
  await navigator.clipboard.writeText(snippet);
  copyBtn.textContent = 'Copied!';
});

C’est le bouton « copier l’extrait de code » présent sur tous les sites de documentation. L’écriture est Baseline et fiable ; la lecture est au mieux optionnelle. readText() retourne une chaîne vide quand le presse-papiers ne contient pas de texte, et Firefox la restreint plus sévèrement que l’écriture : la copie est donc le chemin fiable, et la lecture du presse-papiers doit être traitée comme une amélioration progressive. Remplace clipboard.js.

API View Transitions : animer les changements d’état du DOM nativement

View Transitions anime les transitions entre états du DOM avec document.startViewTransition(() => updateDOM()), et comme elle se dégrade gracieusement (pas d’animation, mais le DOM se met quand même à jour dans les navigateurs non compatibles), il est possible de la livrer en production dès aujourd’hui derrière une garde if (document.startViewTransition). Les transitions au sein d’un même document ont atteint le statut Baseline Newly available le 14 octobre 2025, et fonctionnent dans Chrome 111+, Edge 111+, Firefox 144+ et Safari 18+.

function updatePage(newContent) {
  if (!document.startViewTransition) {
    render(newContent); // fallback: instant update, no animation
    return;
  }
  document.startViewTransition(() => render(newContent));
}

Utilisez-la pour les changements d’onglets, les navigations liste-vers-détail et les changements de filtres — les fondus enchaînés et les morphings d’éléments partagés pour lesquels vous auriez autrement intégré Framer Motion. La garde startViewTransition() fait en sorte que les navigateurs non compatibles appliquent simplement le changement immédiatement. Notez que les transitions entre documents ont une compatibilité plus restreinte : Chrome 126+, Edge 126+ et Safari 18.2+, sans support Firefox pour l’instant — ne confondez pas les deux.

APIs bonus : structuredClone et le piège de fetch

Choisissez l’une de ces APIs pour votre prochain ticket et supprimez la dépendance qu’elle remplace : échangez un listener de scroll contre IntersectionObserver, ou encapsulez un fetch de recherche dans un AbortController. Une mention honorable à garder sous la main : structuredClone() effectue une copie profonde des objets sans passer par un aller-retour JSON.parse(JSON.stringify(...)) et préserve les Dates, Maps, Sets et tableaux typés, bien qu’il lève une DataCloneError sur les fonctions et les nœuds DOM — il est donc destiné aux données, pas aux objets vivants (Baseline depuis mars 2022). Et si fetch reste votre base, rappelez-vous que sa promesse ne rejette pas sur les erreurs HTTP 404 ou 500, uniquement en cas d’échec réseau — vérifiez donc response.ok vous-même.

Questions fréquentes

Quelle est la différence entre IntersectionObserver et ResizeObserver ?

IntersectionObserver signale quand un élément entre dans le viewport ou dans un ancêtre ou en sort, ce qui permet de piloter le chargement différé, le défilement infini et l'analyse de visibilité. ResizeObserver signale les changements des dimensions de la boîte de contenu ou de bordure propres à un élément, ce qui permet de piloter des mises en page adaptatives au conteneur. IntersectionObserver répond à la question « cet élément est-il visible ? », ResizeObserver répond à « quelle est la taille de cet élément ? ». Ce sont des questions différentes, et aucune ne remplace le rôle de l'événement resize de la fenêtre au niveau du viewport.

Dois-je utiliser AbortSignal.timeout() ou un AbortController manuel pour annuler des requêtes fetch ?

Utilisez AbortSignal.timeout() lorsque vous n'avez besoin que d'un timeout fixe, car il annule automatiquement après le nombre de millisecondes indiqué avec une TimeoutError et ne nécessite pas de variable controller. Utilisez un AbortController manuel lorsque l'annulation est déclenchée par un événement que vous contrôlez, comme le nettoyage d'un effet React au démontage ou lors d'une re-navigation, où vous appelez controller.abort() vous-même. Les deux lèvent des erreurs différentes — TimeoutError versus AbortError — ce qui permet à un seul bloc catch de les distinguer.

Pourquoi navigator.clipboard.writeText() échoue-t-il sur mon site de développement local ?

navigator.clipboard.writeText() ne fonctionne que dans un contexte sécurisé, c'est-à-dire HTTPS ou localhost. Si vous accédez à un serveur de développement via une adresse HTTP simple, comme une IP locale ou un nom d'hôte autre que localhost, le navigateur bloque les écritures dans le presse-papiers et la promesse est rejetée. Utilisez localhost ou servez votre application via HTTPS. La lecture avec readText() est encore plus restreinte, notamment dans Firefox — traitez donc l'écriture comme le chemin fiable et la lecture du presse-papiers comme une amélioration progressive.

L'API View Transitions est-elle sûre à utiliser si certains navigateurs ne la prennent pas en charge ?

Oui, car elle se dégrade gracieusement. Protégez l'appel avec if (document.startViewTransition) avant de l'invoquer ; dans les navigateurs qui ne la prennent pas en charge, la mise à jour du DOM s'exécute quand même, mais s'applique immédiatement sans animation. Les transitions au sein d'un même document ont atteint le statut Baseline Newly available le 14 octobre 2025, dans Chrome 111+, Edge 111+, Firefox 144+ et Safari 18+. Les transitions entre documents ont une compatibilité plus restreinte : Chrome 126+, Edge 126+ et Safari 18.2+, sans support Firefox pour l'instant.

Open-source session replay

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.