Compare commits

...

2 commits

Author SHA1 Message Date
cas
b6c89e548d fix: infinite scroll sneller — rootMargin 1200px + 3 batches per trigger
Was: rootMargin=200px, 1 batch (50 items) per intersection trigger
→ bij snel scrollen moest je wachten of terugscrollen

Nu: rootMargin=1200px, tot 3 batches (150 items) per trigger
→ sentinel wordt 1200px eerder gedetecteerd, batches pre-loaden agressief
→ sentinel blijft ver voor de viewport, nooit meer wachten
2026-07-24 11:17:47 +02:00
cas
cb5bb43453 fix: infinite scroll te traag — rootMargin 200px→1200px, tot 3 batches per trigger 2026-07-24 11:17:44 +02:00
3 changed files with 22 additions and 8 deletions

View file

@ -2771,9 +2771,16 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
searchObserver = new IntersectionObserver((entries) => { searchObserver = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) { if (entries[0].isIntersecting) {
// Load up to 3 batches at once when user scrolls fast
// This keeps the sentinel pushed far ahead of the viewport
let batchesLoaded = 0;
const maxBatches = 3;
while (batchesLoaded < maxBatches && searchVisibleCount < allItems.length) {
appendSearchBatch(allItems); appendSearchBatch(allItems);
batchesLoaded++;
} }
}, { rootMargin: '200px' }); }
}, { rootMargin: '1200px' });
searchObserver.observe(sentinel); searchObserver.observe(sentinel);
} }

View file

@ -2771,9 +2771,16 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
searchObserver = new IntersectionObserver((entries) => { searchObserver = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) { if (entries[0].isIntersecting) {
// Load up to 3 batches at once when user scrolls fast
// This keeps the sentinel pushed far ahead of the viewport
let batchesLoaded = 0;
const maxBatches = 3;
while (batchesLoaded < maxBatches && searchVisibleCount < allItems.length) {
appendSearchBatch(allItems); appendSearchBatch(allItems);
batchesLoaded++;
} }
}, { rootMargin: '200px' }); }
}, { rootMargin: '1200px' });
searchObserver.observe(sentinel); searchObserver.observe(sentinel);
} }

View file

@ -456,14 +456,14 @@ test.describe('Karby Eetdagboek', () => {
// Sentinel should exist (there are more than 50 items) // Sentinel should exist (there are more than 50 items)
await expect(page.locator('#searchSentinel')).toBeAttached({ timeout: 3000 }); await expect(page.locator('#searchSentinel')).toBeAttached({ timeout: 3000 });
// Scroll sentinel into view to trigger next batch // Scroll sentinel into view to trigger next batches (now loads 3 at once)
await page.locator('#searchSentinel').scrollIntoViewIfNeeded(); await page.locator('#searchSentinel').scrollIntoViewIfNeeded();
await page.waitForTimeout(800); await page.waitForTimeout(1200);
// Now more items should be rendered // Now more items should be rendered (up to 3 batches of 50)
const afterScrollCount = await page.locator('.food-item').count(); const afterScrollCount = await page.locator('.food-item').count();
expect(afterScrollCount).toBeGreaterThan(initialCount); expect(afterScrollCount).toBeGreaterThan(initialCount);
expect(afterScrollCount).toBeLessThanOrEqual(100); // 2nd page = 100 max expect(afterScrollCount).toBeLessThanOrEqual(200); // max 4 batches total (50 + 3×50)
}); });
test('infinite scroll: search query resets pagination', async ({ page }) => { test('infinite scroll: search query resets pagination', async ({ page }) => {