From f74d07245ffadcae4a2e060161eb537362c6b007 Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Wed, 12 Aug 2015 15:19:10 -0700 Subject: [PATCH] Reduce keySplices to minimum change set before notifying. Fixes #2261 --- src/lib/collection.html | 48 ++++++++++++++++++-------------- src/lib/template/dom-repeat.html | 25 +++++++++-------- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/lib/collection.html b/src/lib/collection.html index 04d44087cc..69c40ad415 100644 --- a/src/lib/collection.html +++ b/src/lib/collection.html @@ -106,32 +106,38 @@ }, _applySplices: function(splices) { - var keySplices = []; - for (var i=0; i 0) { added.push(key); } - // Record splice - keySplices.push({ - index: s.index, - removed: removed, - removedItems: s.removed, - added: added - }); } - return keySplices; + return [{ + removed: removed, + added: added + }]; } }; diff --git a/src/lib/template/dom-repeat.html b/src/lib/template/dom-repeat.html index 538bf8541e..a1537efc68 100644 --- a/src/lib/template/dom-repeat.html +++ b/src/lib/template/dom-repeat.html @@ -268,11 +268,13 @@ this._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', this.items)); } - this._splices = []; + this._keySplices = []; + this._indexSplices = []; this._needFullRefresh = true; this._debounceTemplate(this._render); } else if (change.path == 'items.splices') { - this._splices = this._splices.concat(change.value.keySplices); + this._keySplices = this._keySplices.concat(change.value.keySplices); + this._indexSplices = this._indexSplices.concat(change.value.indexSplices); this._debounceTemplate(this._render); } else { // items.* // slice off 'items.' ('items.'.length == 6) @@ -303,10 +305,10 @@ }, /** - * Forces the element to render its content. Normally rendering is - * asynchronous to a provoking change. This is done for efficiency so - * that multiple changes trigger only a single render. The render method - * should be called if, for example, template rendering is required to + * Forces the element to render its content. Normally rendering is + * asynchronous to a provoking change. This is done for efficiency so + * that multiple changes trigger only a single render. The render method + * should be called if, for example, template rendering is required to * validate application state. */ render: function() { @@ -324,17 +326,18 @@ this._needFullRefresh = false; } else { if (this._sortFn) { - this._applySplicesUserSort(this._splices); + this._applySplicesUserSort(this._keySplices); } else { if (this._filterFn) { // TODK(kschaaf): Filtering using array sort takes slow path this._applyFullRefresh(); } else { - this._applySplicesArrayOrder(this._splices); + this._applySplicesArrayOrder(this._indexSplices); } } } - this._splices = []; + this._keySplices = []; + this._indexSplices = []; // Update final _keyToInstIdx and instance indices var keyToIdx = this._keyToInstIdx = {}; for (var i=0; i