From 32d7d61d4f6674f51089aebed8f7da508b03c33f Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Wed, 1 Jul 2020 12:03:13 -0700 Subject: [PATCH 1/2] Cancel chunking when disconnected. Fixes #5667 --- lib/elements/dom-repeat.js | 13 ++++++++++++- test/unit/dom-repeat.html | 29 +++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/lib/elements/dom-repeat.js b/lib/elements/dom-repeat.js index 3a2c7d9175..c4b77958a7 100644 --- a/lib/elements/dom-repeat.js +++ b/lib/elements/dom-repeat.js @@ -346,6 +346,10 @@ export class DomRepeat extends domRepeatBase { for (let i=0; i this.__continueChunking()); + this.__chunkingId = requestAnimationFrame(() => { + this.__chunkingId = null; + this.__continueChunking(); + }); } // Set rendered item count this._setRenderedItemCount(this.__instances.length); diff --git a/test/unit/dom-repeat.html b/test/unit/dom-repeat.html index 119149d412..84c96f5799 100644 --- a/test/unit/dom-repeat.html +++ b/test/unit/dom-repeat.html @@ -3933,16 +3933,24 @@

x-repeat-limit

suite('chunked rendering', function() { let chunked; - let resolve; + let notifyChange; let targetCount; - const handleChange = () => { + let handleChange = () => { if (!targetCount || chunked.$.repeater.renderedItemCount >= targetCount) { - resolve(Array.from(chunked.root.querySelectorAll('*:not(template):not(dom-repeat)'))); + notifyChange(Array.from(chunked.root.querySelectorAll('*:not(template):not(dom-repeat)'))); } }; const waitUntilRendered = async (count) => { targetCount = count; - return await new Promise(r => resolve = r); + return await new Promise(r => notifyChange = r); + }; + const expectNoChanges = async () => { + targetCount = null; + notifyChange = () => { + assert.fail('no changes were expected'); + }; + // Ensure no changes happen in the next rAF+sT + await new Promise(r => requestAnimationFrame(() => setTimeout(() => r()))); }; setup(() => { chunked = document.createElement('x-repeat-chunked'); @@ -4259,6 +4267,19 @@

x-repeat-limit

assert.isAtLeast(frameCount, 2); }); + test('chunking stops after detaching, restarts after attaching', async () => { + chunked.items = chunked.preppedItems.slice(); + const initialLength = (await waitUntilRendered()).length; + assert.isAbove(initialLength, 0); + assert.isBelow(initialLength, chunked.preppedItems.length); + document.body.removeChild(chunked); + await expectNoChanges(); + const done = waitUntilRendered(chunked.preppedItems.length); + document.body.appendChild(chunked); + const endLength = (await done).length; + assert.equal(endLength, chunked.items.length); + }); + }); suite('misc', function() { From 04a4ded879e1bf013b410ac77b1eba836acb4404 Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Mon, 6 Jul 2020 14:21:40 -0700 Subject: [PATCH 2/2] Fix let back to const --- test/unit/dom-repeat.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/dom-repeat.html b/test/unit/dom-repeat.html index 84c96f5799..e70b1a338a 100644 --- a/test/unit/dom-repeat.html +++ b/test/unit/dom-repeat.html @@ -3935,7 +3935,7 @@

x-repeat-limit

let chunked; let notifyChange; let targetCount; - let handleChange = () => { + const handleChange = () => { if (!targetCount || chunked.$.repeater.renderedItemCount >= targetCount) { notifyChange(Array.from(chunked.root.querySelectorAll('*:not(template):not(dom-repeat)'))); }