Add fast path for appending updates to the end of the queue
This is the most common case, so we should avoid scanning the entire list to get to the end.
Andrew Clark committed
Dec 13, 2016 at 10:55 UTC
babace0c059965b01767797adace4e765a4650d7
1 file changed
+31
-22
src/renderers/shared/fiber/ReactFiberUpdateQueue.js
+31
-22
@@ -176,26 +176,41 @@ function insertUpdate(fiber : Fiber, update : Update) : void {
176
177
const priorityLevel = update.priorityLevel;
178
179
- // TODO: Fast path where last item in the queue has greater or equal priority.
180
-
181
- let insertAfter1 = null;
182
- let insertBefore1 = queue1.first;
183
- while (insertBefore1 && comparePriority(insertBefore1.priorityLevel, priorityLevel) <= 0) {
184
- insertAfter1 = insertBefore1;
185
- insertBefore1 = insertBefore1.next;
179
+ let queue = queue1;
180
+ let insertAfter1;
181
+ let insertBefore1;
182
+ let insertAfter2;
183
+ let insertBefore2;
184
+ for (let i = 0; queue && i < 2; i++) {
185
+ let insertAfter = null;
186
+ let insertBefore = null;
187
+ if (queue.last && comparePriority(queue.last.priorityLevel, priorityLevel) <= 0) {
188
+ // Fast path for the common case where the update should be inserted at
189
+ // the end of the queue.
190
+ insertAfter = queue.last;
191
+ } else {
192
+ insertBefore = queue.first;
193
+ while (insertBefore && comparePriority(insertBefore.priorityLevel, priorityLevel) <= 0) {
194
+ insertAfter = insertBefore;
195
+ insertBefore = insertBefore.next;
196
+ }
197
+ }
198
+ if (i === 0) {
199
+ insertAfter1 = insertAfter;
200
+ insertBefore1 = insertBefore;
201
+ queue = queue2;
202
+ } else {
203
+ insertAfter2 = insertAfter;
204
+ insertBefore2 = insertBefore;
205
+ queue = null;
206
+ }
207
}
208
+
209
const update1 = update;
210
+ insertUpdateIntoQueue(queue1, update1, insertAfter1, insertBefore1);
211
189
- let insertAfter2 = null;
190
- let insertBefore2 = null;
191
- let update2 = null;
212
if (queue2) {
193
- insertBefore2 = queue2.first;
194
- while (insertBefore2 && comparePriority(insertBefore2.priorityLevel, priorityLevel) <= 0) {
195
- insertAfter2 = insertBefore2;
196
- insertBefore2 = insertBefore2.next;
197
- }
198
-
213
+ let update2;
214
if (insertBefore1 === insertBefore2) {
215
// The update is inserted into the same position of both lists. There's no
216
// need to clone the update.
@@ -206,11 +221,6 @@ function insertUpdate(fiber : Fiber, update : Update) : void {
221
// time we commit.
222
update2 = cloneUpdate(update1);
223
}
209
- }
210
-
211
- // Now we're ready to insert the updates into their queues.
212
- insertUpdateIntoQueue(queue1, update1, insertAfter1, insertBefore1);
213
- if (queue2 && update2) {
224
insertUpdateIntoQueue(queue2, update2, insertAfter2, insertBefore2);
225
}
226
}
@@ -296,7 +306,6 @@ exports.addForceUpdate = addForceUpdate;
306
307
308
function addCallback(fiber : Fiber, callback: Callback, priorityLevel : PriorityLevel) : void {
299
- // TODO: Fast path where last item in queue has equal priority.
309
const update : Update = {
310
priorityLevel,
311
partialState: null,