Le défilement infini (Infinite Scroll) est une technique de chargement automatique du contenu lorsque l’utilisateur atteint le bas de la liste actuelle. Selon UX Design Collective, 2024, l’Infinite Scroll augmente le temps de session dans les réseaux sociaux de 40–60% par rapport à la pagination. Dans le développement mobile, cette technique est implémentée via une combinaison d’écouteurs de défilement et de requêtes API avec une pagination basée sur curseur. Le défilement infini est devenu la norme de facto pour les flux de contenu, mais nécessite une implémentation minutieuse pour éviter les problèmes de performances et de navigation.
Points Clés
Le défilement infini (Infinite Scroll) est un modèle de chargement de données dans lequel de nouveaux éléments sont automatiquement ajoutés à la fin de la liste au fur et à mesure que l’utilisateur défile. L’utilisateur ne clique pas sur les boutons «Suivant» ou «Charger plus» — le système lui-même détermine quand demander le lot de données suivant et insère de nouvelles entrées de manière transparente dans la liste existante.
L’Infinite Scroll a gagné en popularité grâce aux réseaux sociaux — Twitter, Instagram et TikTok l’utilisent comme mécanisme principal de distribution de contenu. Selon Nielsen Norman Group (2024), le défilement infini augmente l’engagement de 30–50% pour les applications de contenu car il réduit la charge cognitive : l’utilisateur n’a pas besoin de décider d’aller à la page suivante. Cependant, pour les tâches nécessitant une navigation précise (recherche, comparaison de produits), le défilement infini peut réduire l’efficacité.
Techniquement, le défilement infini se compose de trois composants : un écouteur de défilement (suit la position de défilement), un seuil (distance jusqu’à la fin de la liste pour déclencher le chargement) et un mécanisme de pagination (requête API et insertion de données). La configuration correcte du seuil est critique : si le déclencheur est trop tôt (1000 px de la fin), l’utilisateur recevra des requêtes inutiles ; s’il est trop tard (50 px), l’utilisateur remarquera une pause de chargement.
L’architecture du défilement infini est basée sur un modèle piloté par les événements : le composant de liste génère un événement lorsque le seuil de défilement est atteint, le ViewModel le traite et appelle le référentiel pour charger le lot de données suivant. Après avoir reçu la réponse, de nouveaux éléments sont insérés dans la liste et l’interface utilisateur est mise à jour via l’adaptateur. Cette chaîne doit être asynchrone et ne doit pas bloquer le thread de l’interface utilisateur.
L’algorithme de base du défilement infini comprend quatre étapes. Initialisation : lors de la première ouverture de l’écran, le premier lot de données est chargé (page 1 ou curseur = null). Suivi : l’écouteur de défilement vérifie si l’utilisateur a atteint le seuil — généralement 200–500 px de la fin de la liste. Chargement : une requête est envoyée à l’API avec des paramètres de pagination, un indicateur de chargement (spinner dans le pied de page) est affiché sur l’interface. Insertion : de nouveaux éléments sont ajoutés à l’adaptateur, la position de défilement est ajustée pour éviter les sauts.
Un aspect critique est le debounce des requêtes. Si l’utilisateur défile rapidement jusqu’à la fin, le déclencheur peut se produire plusieurs fois avant de recevoir une réponse du serveur. Sans debounce, cela entraîne des requêtes en double (condition de concurrence). La solution consiste à bloquer les nouvelles requêtes jusqu’à ce que la précédente soit terminée. Un indicateur isLoading dans le ViewModel empêche les appels multiples : définissez isLoading = true lors de l’envoi d’une requête, réinitialisez-le lors de la réception d’une réponse ou d’une erreur.
Sur les plateformes mobiles, des mécanismes spécialisés sont utilisés pour le défilement infini. Sur iOS, il s’agit du prefetchDataSource dans UICollectionView, qui demande automatiquement les données pour les cellules hors écran. Sur Android, il s’agit de la bibliothèque Paging 3 de Google, qui fournit une architecture prête à l’emploi avec PagingSource, PagingData et PagingDataAdapter. Paging 3 prend en charge RemoteMediator pour combiner les données réseau et locales et gère automatiquement l’état de chargement.
La pagination basée sur le décalage (offset-based) utilise les paramètres de page et de taille : page=2, size=20 renvoie les enregistrements 21–40. Cette approche est simple à implémenter mais présente un problème fondamental — si des enregistrements sont ajoutés ou supprimés de la base de données entre les requêtes, le décalage se désynchronise (l’utilisateur voit des doublons ou des lacunes). Pour les flux à fréquence élevée de modifications (actualités, commentaires), la pagination basée sur le décalage produit des résultats incorrects.
La pagination basée sur curseur (cursor-based) utilise un identifiant unique du dernier élément (curseur) : after=id_12345&limit=20. Le serveur renvoie 20 enregistrements après le curseur spécifié. Cette approche garantit la cohérence des données indépendamment des insertions et des suppressions. Selon GraphQL Best Practices (2024), la pagination basée sur curseur est recommandée pour toutes les applications en temps réel où les données changent dynamiquement.
Le choix entre les approches dépend du type d’application. Pour les réseaux sociaux (Instagram, TikTok) — uniquement basée sur curseur, car le flux est constamment mis à jour. Pour les catalogues à modifications rares (catégories de produits de boutiques en ligne), la pagination basée sur le décalage est acceptable. Pour les scénarios hybrides, Google recommande Paging 3 RemoteMediator, qui combine la pagination basée sur curseur du réseau avec la pagination basée sur le décalage de la base de données locale Room.
Sur Android, l’approche standard est la bibliothèque Paging 3 de Jetpack. PagingSource définit la source de données (réseau ou base de données), PagingData contient des morceaux de données et PagingDataAdapter les affiche dans RecyclerView. Paging 3 gère automatiquement la distance de préchargement, les tentatives et l’actualisation. Pour l’intégration réseau, RemoteMediator est utilisé : il charge les données depuis l’API, les sauvegarde dans Room et notifie PagingSource des mises à jour. Selon Google I/O 2024, plus de 60% des applications Android avec défilement infini utilisent Paging 3.
Exemple d’implémentation de base de Paging 3 :
class FeedPagingSource(
private val api: FeedApi
) : PagingSource<String, Post>() {
override suspend fun load(
params: LoadParams<String>
): LoadResult<String, Post> {
val response = api.getFeed(
cursor = params.key,
limit = params.loadSize
)
return LoadResult.Page(
data = response.items,
prevKey = null,
nextKey = response.nextCursor
)
}
}
Sur iOS, le défilement infini est implémenté en utilisant UICollectionView avec prefetchDataSource. Le protocole UICollectionViewDataSourcePrefetching contient la méthode collectionView(_:prefetchItemsAt:), qui est appelée lorsque le système anticipe un défilement vers certains index paths. Contrairement à Android Paging 3, iOS n’a pas de bibliothèque de pagination intégrée — les développeurs l’implémentent manuellement ou utilisent des solutions tierces comme RxSwift + NSLayoutConstraint ou des pipelines basés sur Combine.
Exemple de préchargement sur iOS :
extension FeedViewController: UICollectionViewDataSourcePrefetching {
func collectionView(
_ collectionView: UICollectionView,
prefetchItemsAt indexPaths: [IndexPath]
) {
let lastRow = collectionView.numberOfItems(inSection: 0) - 1
if indexPaths.contains(IndexPath(row: lastRow, section: 0)) {
viewModel.loadNextPage()
}
}
}
SwiftUI offre une approche plus déclarative via le modificateur onAppear. Le développeur place un ProgressView à la fin de la liste et lorsqu’il apparaît, déclenche le chargement de la page suivante. Selon Apple WWDC 2024, les nouvelles API AsyncSequence et Swift Algorithms simplifient l’implémentation du défilement infini en fournissant des opérateurs intégrés de chunking et de debounce.
Le principal problème UX du défilement infini est la perte du pied de page et de la navigation. Dans les boutiques en ligne, les utilisateurs veulent souvent aller au pied de page pour les contacts ou les liens. Le défilement infini rend le pied de page inaccessible — il descend continuellement au fur et à mesure que davantage de contenu est chargé. La solution consiste à ajouter un bouton d’action flottant (FAB) pour un défilement rapide vers le haut ou à fixer le pied de page séparément de la liste.
Le deuxième problème est l’absence d’historique de défilement. Si un utilisateur voit un produit intéressant à la position 3, défile jusqu’à la position 50, puis appuie sur «Retour» — il revient en haut de la liste et doit défiler à nouveau jusqu’à la position 50. La solution consiste à sauvegarder la position de défilement dans le ViewModel ou à utiliser la restauration d’état au niveau Activity/UIViewController. iOS prend en charge NSUserActivity pour la restauration de position, Android prend en charge onSaveInstanceState.
Le troisième problème est les performances avec des milliers d’éléments. Si la virtualisation n’est pas configurée, après 500–1000 éléments chargés, l’application commence à ralentir en raison de l’augmentation de la consommation mémoire. La solution consiste à utiliser la virtualisation avec RecyclerView ou UICollectionView, qui ne conserve en mémoire que les cellules visibles et préchargées. Le nettoyage périodique des anciennes données (abandon des pages au-delà de N pages) réduit également la charge.
Foire aux questions
Le défilement infini (Infinite Scroll) est une technique de chargement automatique du contenu lorsque l’utilisateur atteint le bas de la liste. De nouvelles données sont ajoutées de manière transparente sans qu’il soit nécessaire de cliquer sur les boutons de pagination. Il est utilisé dans les réseaux sociaux, les flux d’actualités et les catalogues à contenu dynamique.
La pagination nécessite une navigation manuelle entre les pages (boutons «1, 2, 3»), tandis que l’Infinite Scroll charge les données automatiquement. La pagination est prévisible et préserve le contexte de navigation ; le défilement infini augmente l’engagement mais complique l’accès au pied de page et à l’historique de défilement. Le choix dépend du type de contenu et des objectifs de l’application.
Sur Android, la bibliothèque recommandée est Paging 3 de Jetpack. Elle fournit PagingSource pour la source de données, PagingData pour les morceaux et PagingDataAdapter pour RecyclerView. Paging 3 gère automatiquement le préchargement, l’état de chargement et les tentatives. Pour les scénarios hybrides hors ligne/en ligne, utilisez RemoteMediator.
Les requêtes en double sont évitées grâce à un indicateur de debounce isLoading. Lorsque la première requête est envoyée, l’indicateur est défini sur true et bloque les nouveaux appels jusqu’à ce qu’une réponse soit reçue. Après une réponse réussie, l’indicateur est réinitialisé. De plus, vous pouvez annuler les coroutines (Kotlin) ou Cancellable (Swift) lors du défilement arrière.
Le défilement infini n’est pas adapté au e-commerce avec recherche et comparaison de produits, aux applications avec un pied de page important (contacts, liens), aux pages de résultats de recherche (l’utilisateur doit revenir à un élément spécifique) et aux pages de statistiques/rapports où le nombre total est important. Dans ces cas, utilisez la pagination classique ou un bouton «Charger plus».
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi