feat: fetch the next page of books before the reader hits the bottom
The prefetch zone is a viewport deep rather than 200px, and the observer re-observes after a page lands so a chain of loads is not cut short.
This commit is contained in:
@@ -29,19 +29,31 @@
|
||||
|
||||
$effect(() => {
|
||||
if (!sentinel || !bookCollection.moreBooks) return;
|
||||
const target = sentinel;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
async (entries) => {
|
||||
if (entries[0].isIntersecting && !bookCollection.loading) {
|
||||
await bookCollection.loadMoreBooks();
|
||||
if (!entries[0].isIntersecting) return;
|
||||
|
||||
await bookCollection.loadMoreBooks();
|
||||
|
||||
// A page that does not push the sentinel back out of the prefetch zone
|
||||
// produces no further intersection change, so the observer would sit
|
||||
// idle until the next scroll. Re-observing asks for a fresh reading.
|
||||
if (bookCollection.moreBooks) {
|
||||
observer.unobserve(target);
|
||||
observer.observe(target);
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
root: scrollContainer,
|
||||
rootMargin: '0px 0px 200px 0px'
|
||||
// One viewport of lead time: the next page is requested a full screen
|
||||
// before the reader reaches the end of the current one.
|
||||
rootMargin: '0px 0px 100% 0px'
|
||||
}
|
||||
);
|
||||
|
||||
observer.observe(sentinel);
|
||||
observer.observe(target);
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
@@ -110,7 +122,7 @@
|
||||
|
||||
{#if bookCollection.moreBooks}
|
||||
<div bind:this={sentinel}>
|
||||
{#if bookCollection.loading}
|
||||
{#if bookCollection.loadingMore}
|
||||
<Spinner />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user