From 4259d26c973a6930ba693040ef53439b97ef009a Mon Sep 17 00:00:00 2001 From: David Manthey Date: Wed, 11 May 2022 13:08:32 -0400 Subject: [PATCH] perf: Optimize reordering fetch queue When reordering an existing item in a fetch queue, instead of splicing it out of the queue and splicing it back in, shift existing components and add it. This is faster than splicing. --- src/fetchQueue.js | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/fetchQueue.js b/src/fetchQueue.js index 06bae77c05..df719bb3f3 100644 --- a/src/fetchQueue.js +++ b/src/fetchQueue.js @@ -146,8 +146,8 @@ var fetchQueue = function (options) { if (defer.__fetchQueue) { var pos = $.inArray(defer, m_this._queue); if (pos >= 0) { - m_this._queue.splice(pos, 1); - m_this._addToQueue(defer, atEnd); + // m_this._queue.splice(pos, 1); + m_this._addToQueue(defer, atEnd, pos); return defer; } } @@ -177,20 +177,34 @@ var fetchQueue = function (options) { * @param {boolean} atEnd If falsy, add the item to the front of the queue * if batching is turned off or at the end of the current batch if it is * turned on. If truthy, always add the item to the end of the queue. + * @param {number} [pos] If specified, the current location in the queue of + * the object being added. This avoids having to splice, push, or unshift + * the queue. */ - this._addToQueue = function (defer, atEnd) { + this._addToQueue = function (defer, atEnd, pos) { + let move = atEnd ? m_this._queue.length - 1 : 0; defer.__fetchQueue._batch = m_this._batch; - if (atEnd) { - m_this._queue.push(defer); - } else if (!m_this._batch) { - m_this._queue.unshift(defer); - } else { - for (var i = 0; i < m_this._queue.length; i += 1) { - if (m_this._queue[i].__fetchQueue._batch !== m_this._batch) { + if (!atEnd && m_this._batch) { + for (move = 0; move < m_this._queue.length - (pos === undefined ? 0 : 1); move += 1) { + if (m_this._queue[move].__fetchQueue._batch !== m_this._batch) { break; } } - m_this._queue.splice(i, 0, defer); + } + if (pos === undefined) { + if (atEnd) { + m_this._queue.push(defer); + } else if (!move) { + m_this._queue.unshift(defer); + } else { + m_this._queue.splice(move, 0, defer); + } + } else if (pos !== move) { + const dir = pos < move ? 1 : -1; + for (let i = pos; i !== move; i += dir) { + m_this._queue[i] = m_this._queue[i + dir]; + } + m_this._queue[move] = defer; } };