Optimizing Infinite Scroll Performance
Highlights techniques for optimizing the performance of an infinite scroll feature, including debouncing scroll events and efficiently managing the cache with React Query.
import { useInfiniteQuery } from 'react-query';
import { useEffect, useState } from 'react';
function useInfinitePosts() {
return useInfiniteQuery(
'posts',
async ({ pageParam = 1 }) => {
const response = await fetch(`/api/posts?page=${pageParam}`);
return response.json();
},
{
getNextPageParam: (lastPage, pages) => lastPage.nextPage ?? false
}
);
}
This code snippet demonstrates how to fetch data in chunks using React Query's 'useInfiniteQuery' hook. Each chunk corresponds to a 'page' of data from the API. The 'getNextPageParam' returns the value for the next page, or false if there are no more pages.
import { useRef, useCallback } from 'react';
import { useIntersectionObserver } from './useIntersectionObserver';
const InfiniteScrollComponent = ({ data, fetchNextPage }) => {
const loadMoreRef = useRef();
useIntersectionObserver({
target: loadMoreRef,
onIntersect: fetchNextPage,
enabled: data?.hasNextPage,
});
return (
<div>
{data.pages.map(page => (
<React.Fragment key={page.key}>
{page.items.map(item => <div key={item.id}>{item.title}</div>)}
</React.Fragment>
))}
<div ref={loadMoreRef}>Load More</div>
</div>
);
}
This code implements the UI component and utilizes an IntersectionObserver hook (`useIntersectionObserver`) to detect when the `Load More` div becomes visible on screen, triggering `fetchNextPage`. The `ref` attached to the `Load More` div moves down with each data fetch, ensuring smooth infinite scrolling.
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
This is a debounce function, used to limit the number of times a function (like scrolling events) can be executed over time. This can enhance performance by reducing the number of API calls or heavy computations when scrolling rapidly.