Détecter l'entrée d'éléments dans la zone d'affichage avec Intersection Observer

Le suivi de la visibilité des éléments avec des écouteurs d’événements de défilement peut considérablement dégrader les performances de votre site web. Chaque défilement déclenche plusieurs événements, chacun appelant getBoundingClientRect()
et forçant des recalculs coûteux du navigateur. L’API Intersection Observer résout ce problème de manière élégante, fournissant une optimisation native du navigateur pour détecter quand des éléments entrent ou sortent de la zone d’affichage.
Points clés à retenir
- Intersection Observer élimine les goulots d’étranglement de performance causés par les écouteurs d’événements de défilement
- L’API fonctionne de manière asynchrone, empêchant le blocage du thread principal
- Un seul observateur peut surveiller efficacement plusieurs éléments
- L’optimisation native du navigateur offre de meilleures performances que les calculs manuels
Pourquoi les événements de défilement traditionnels sont insuffisants
Les écouteurs d’événements de défilement se déclenchent continuellement pendant le défilement, souvent plus de 60 fois par seconde. Chaque gestionnaire d’événement qui appelle getBoundingClientRect()
force le navigateur à recalculer les mises en page, créant des expériences de défilement saccadées. Lorsque plusieurs bibliothèques suivent la visibilité de manière indépendante—pour les publicités, l’analytique et le chargement différé—l’impact sur les performances se multiplie dramatiquement.
L’approche Intersection Observer déplace ces calculs hors du thread principal, permettant au navigateur d’optimiser quand et comment les vérifications d’intersection se produisent.
Comprendre les bases d’Intersection Observer
L’API Intersection Observer surveille de manière asynchrone les éléments cibles qui franchissent les limites avec un élément racine (généralement la zone d’affichage). Au lieu d’un sondage constant, elle vous notifie uniquement lorsque les seuils de visibilité sont franchis.
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log('Element is visible');
}
});
});
observer.observe(document.querySelector('.target'));
Le navigateur gère tous les calculs d’intersection en interne, livrant les résultats via un callback avec des objets IntersectionObserverEntry
. Chaque entrée fournit isIntersecting
(booléen) et intersectionRatio
(pourcentage de visibilité de 0 à 1).
Créer votre premier observateur
Configurer un Intersection Observer ne nécessite qu’une fonction de callback et une configuration optionnelle :
const callback = (entries, observer) => {
entries.forEach(entry => {
// Propriétés clés disponibles
console.log({
isVisible: entry.isIntersecting,
visibilityRatio: entry.intersectionRatio,
targetElement: entry.target
});
});
};
const options = {
root: null, // zone d'affichage
rootMargin: '0px', // aucun décalage
threshold: 0.5 // 50% visible
};
const observer = new IntersectionObserver(callback, options);
observer.observe(document.querySelector('.target'));
Le callback reçoit un tableau d’entrées car les observateurs peuvent suivre plusieurs éléments simultanément. La propriété isIntersecting
de chaque entrée indique la visibilité actuelle, tandis qu’intersectionRatio
fournit le pourcentage de visibilité précis.
Configurer les options de l’observateur
Trois options contrôlent quand les callbacks d’intersection se déclenchent :
root : Définit la zone défilable à surveiller. null
utilise la zone d’affichage ; tout élément défilable peut servir de racine personnalisée.
rootMargin : Étend ou réduit la boîte englobante de la racine. Utilisez la syntaxe de marge CSS : "50px"
ou "10% 0px"
. Les valeurs négatives réduisent ; les valeurs positives étendent la zone de détection.
threshold : Pourcentage(s) de visibilité déclenchant les callbacks. Valeur unique : 0.5
(50%). Tableau pour plusieurs déclencheurs : [0, 0.25, 0.5, 0.75, 1]
.
Discover how at OpenReplay.com.
Surveiller plusieurs éléments efficacement
Une instance d’observateur peut surveiller un nombre illimité d’éléments :
const observer = new IntersectionObserver(callback, options);
const targets = document.querySelectorAll('.lazy-load');
targets.forEach(target => observer.observe(target));
// Arrêter de surveiller des éléments spécifiques
// observer.unobserve(element);
// Arrêter de surveiller tous les éléments
// observer.disconnect();
Ce modèle maximise l’efficacité—le navigateur optimise mieux un seul observateur surveillant des centaines d’éléments que plusieurs observateurs.
Exemples d’implémentation réels
Chargement différé d’images
const imageObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
imageObserver.unobserve(img);
}
});
}, { rootMargin: '50px' });
document.querySelectorAll('img[data-src]').forEach(img => {
imageObserver.observe(img);
});
Déclencher des animations au défilement
const animationObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate');
}
});
}, { threshold: 0.1 });
document.querySelectorAll('.animate-on-scroll').forEach(element => {
animationObserver.observe(element);
});
Lecture automatique de vidéos en vue
const videoObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
const video = entry.target;
if (entry.isIntersecting) {
video.play();
} else {
video.pause();
}
});
}, { threshold: 0.5 });
document.querySelectorAll('video').forEach(video => {
videoObserver.observe(video);
});
Conclusion
L’API Intersection Observer transforme la détection de zone d’affichage d’un goulot d’étranglement de performance en une fonctionnalité optimisée du navigateur. En remplaçant les écouteurs d’événements de défilement par des observateurs d’intersection, vous éliminez le blocage du thread principal tout en gagnant un contrôle de visibilité plus précis. Commencez dès aujourd’hui à migrer votre code de visibilité basé sur le défilement—les navigateurs de vos utilisateurs vous en remercieront.
FAQ
Oui, appelez simplement observer.observe() sur les nouveaux éléments après leur ajout au DOM. La même instance d'observateur peut surveiller des éléments ajoutés à tout moment pendant le cycle de vie de la page.
Le callback se déclenche immédiatement avec l'état d'intersection actuel de l'élément. Cela garantit que vous connaissez toujours le statut de visibilité initial sans avoir besoin de vérifications séparées.
Vérifiez que entry.isIntersecting est false dans votre callback. L'observateur vous notifie à la fois quand les éléments entrent et sortent de la zone observée selon vos paramètres de seuil.
Les navigateurs modernes le prennent en charge nativement. Pour les navigateurs plus anciens comme Internet Explorer, utilisez le polyfill officiel du W3C qui fournit une fonctionnalité identique via JavaScript.
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.