Skip to content

Commit

Permalink
Merge pull request #5640 from Polymer/legacy-undefined-noBatch-5631-2
Browse files Browse the repository at this point in the history
Ensure limit is reset when initialCount is disabled.
  • Loading branch information
kevinpschaaf authored Mar 5, 2020
2 parents 5421b5b + ddb37df commit 22e1d02
Show file tree
Hide file tree
Showing 3 changed files with 472 additions and 388 deletions.
99 changes: 52 additions & 47 deletions lib/elements/dom-repeat.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,12 @@ export class DomRepeat extends domRepeatBase {
},

/**
* Defines an initial count of template instances to render after setting
* the `items` array, before the next paint, and puts the `dom-repeat`
* into "chunking mode". The remaining items (and any future items as a
* result of pushing onto the array) will be created and rendered
* incrementally at each animation frame thereof until all instances have
* been rendered.
* When greater than zero, defines an initial count of template instances
* to render after setting the `items` array, before the next paint, and
* puts the `dom-repeat` into "chunking mode". The remaining items (and
* any future items as a result of pushing onto the array) will be created
* and rendered incrementally at each animation frame thereof until all
* instances have been rendered.
*/
initialCount: {
type: Number
Expand Down Expand Up @@ -317,14 +317,14 @@ export class DomRepeat extends domRepeatBase {
constructor() {
super();
this.__instances = [];
this.__limit = Infinity;
this.__renderDebouncer = null;
this.__itemsIdxToInstIdx = {};
this.__chunkCount = null;
this.__renderStartTime = null;
this.__itemsArrayChanged = false;
this.__shouldMeasureChunk = false;
this.__shouldContinueChunking = false;
this.__chunkingId = 0;
this.__sortFn = null;
this.__filterFn = null;
this.__observePaths = null;
Expand Down Expand Up @@ -542,18 +542,20 @@ export class DomRepeat extends domRepeatBase {
const isntIdxToItemsIdx = this.__sortAndFilterItems(items);
// If we're chunking, increase the limit if there are new instances to
// create and schedule the next chunk
if (this.initialCount) {
this.__updateLimit(isntIdxToItemsIdx.length);
}
const limit = this.__calculateLimit(isntIdxToItemsIdx.length);
// Create, update, and/or remove instances
this.__updateInstances(items, isntIdxToItemsIdx);
// Set rendered item count
this._setRenderedItemCount(this.__instances.length);
// If we're chunking, schedule a rAF task to measure/continue chunking
this.__updateInstances(items, limit, isntIdxToItemsIdx);
// If we're chunking, schedule a rAF task to measure/continue chunking.
// Do this before any notifying events (renderedItemCount & dom-change)
// since those could modify items and enqueue a new full render which will
// pre-empt this measurement.
if (this.initialCount &&
(this.__shouldMeasureChunk || this.__shouldContinueChunking)) {
this.__debounceRender(this.__continueChunkingAfterRaf);
cancelAnimationFrame(this.__chunkingId);
this.__chunkingId = requestAnimationFrame(() => this.__continueChunking());
}
// Set rendered item count
this._setRenderedItemCount(this.__instances.length);
// Notify users
if (!suppressTemplateNotifications || this.notifyDomChange) {
this.dispatchEvent(new CustomEvent('dom-change', {
Expand Down Expand Up @@ -581,36 +583,40 @@ export class DomRepeat extends domRepeatBase {
return isntIdxToItemsIdx;
}

__updateLimit(filteredItemCount) {
let newCount;
if (!this.__chunkCount ||
(this.__itemsArrayChanged && !this.reuseChunkedInstances)) {
// Limit next render to the initial count
this.__limit = Math.min(filteredItemCount, this.initialCount);
// Subtract off any existing instances to determine the number of
// instances that will be created
newCount = Math.max(this.__limit - this.__instances.length, 0);
// Initialize the chunk size with how many items we're creating
this.__chunkCount = newCount || 1;
} else {
// The number of new instances that will be created is based on the
// existing instances, the new list size, and the maximum chunk size
newCount = Math.min(
Math.max(filteredItemCount - this.__instances.length, 0),
this.__chunkCount);
// Update the limit based on how many new items we're making, limited
// buy the total size of the list
this.__limit = Math.min(this.__limit + newCount, filteredItemCount);
__calculateLimit(filteredItemCount) {
let limit = filteredItemCount;
const currentCount = this.__instances.length;
// When chunking, we increase the limit from the currently rendered count
// by the chunk count that is re-calculated after each rAF (with special
// cases for reseting the limit to initialCount after changing items)
if (this.initialCount) {
let newCount;
if (!this.__chunkCount ||
(this.__itemsArrayChanged && !this.reuseChunkedInstances)) {
// Limit next render to the initial count
limit = Math.min(filteredItemCount, this.initialCount);
// Subtract off any existing instances to determine the number of
// instances that will be created
newCount = Math.max(limit - currentCount, 0);
// Initialize the chunk size with how many items we're creating
this.__chunkCount = newCount || 1;
} else {
// The number of new instances that will be created is based on the
// existing instances, the new list size, and the chunk size
newCount = Math.min(
Math.max(filteredItemCount - currentCount, 0),
this.__chunkCount);
// Update the limit based on how many new items we're making, limited
// buy the total size of the list
limit = Math.min(currentCount + newCount, filteredItemCount);
}
// Record some state about chunking for use in `__continueChunking`
this.__shouldMeasureChunk = newCount === this.__chunkCount;
this.__shouldContinueChunking = limit < filteredItemCount;
this.__renderStartTime = performance.now();
}
this.__itemsArrayChanged = false;
// Record some state about chunking for use in `__continueChunking`
this.__shouldMeasureChunk = newCount === this.__chunkCount;
this.__shouldContinueChunking = this.__limit < filteredItemCount;
this.__renderStartTime = performance.now();
}

__continueChunkingAfterRaf() {
requestAnimationFrame(() => this.__continueChunking());
return limit;
}

__continueChunking() {
Expand All @@ -631,13 +637,12 @@ export class DomRepeat extends domRepeatBase {
}
}

__updateInstances(items, isntIdxToItemsIdx) {
__updateInstances(items, limit, isntIdxToItemsIdx) {
// items->inst map kept for item path forwarding
const itemsIdxToInstIdx = this.__itemsIdxToInstIdx = {};
let instIdx = 0;
let instIdx;
// Generate instances and assign items
const limit = Math.min(isntIdxToItemsIdx.length, this.__limit);
for (; instIdx<limit; instIdx++) {
for (instIdx=0; instIdx<limit; instIdx++) {
let inst = this.__instances[instIdx];
let itemIdx = isntIdxToItemsIdx[instIdx];
let item = items[itemIdx];
Expand Down
Loading

0 comments on commit 22e1d02

Please sign in to comment.