Remove callbackList field from Fiber

Moves it to UpdateQueue instead so that we don't waste memory for
components that don't have update queues.
This commit is contained in:
Andrew Clark
2017-01-09 17:10:10 -08:00
parent b2cc91e83a
commit d4e971a266
4 changed files with 26 additions and 38 deletions
+1 -3
View File
@@ -111,8 +111,7 @@ export type Fiber = {
// A queue of state updates and callbacks.
updateQueue: UpdateQueue | null,
// A list of callbacks that should be called during the next commit.
callbackList: UpdateQueue | null,
// The state used to create the output
memoizedState: any,
@@ -203,7 +202,6 @@ var createFiber = function(tag : TypeOfWork, key : null | string) : Fiber {
pendingProps: null,
memoizedProps: null,
updateQueue: null,
callbackList: null,
memoizedState: null,
effectTag: NoEffect,
@@ -30,6 +30,7 @@ var { commitCallbacks } = require('ReactFiberUpdateQueue');
var {
Placement,
Update,
Callback,
ContentReset,
} = require('ReactTypeOfSideEffect');
@@ -410,17 +411,16 @@ module.exports = function<T, P, I, TI, C, CX, CI>(
}
}
}
const callbackList = finishedWork.callbackList;
if (callbackList) {
commitCallbacks(finishedWork, callbackList, instance);
if ((finishedWork.effectTag & Callback) && finishedWork.updateQueue) {
commitCallbacks(finishedWork, finishedWork.updateQueue, instance);
}
return;
}
case HostRoot: {
const callbackList = finishedWork.callbackList;
if (callbackList) {
const updateQueue = finishedWork.updateQueue;
if (updateQueue) {
const instance = finishedWork.child && finishedWork.child.stateNode;
commitCallbacks(finishedWork, callbackList, instance);
commitCallbacks(finishedWork, updateQueue, instance);
}
return;
}
@@ -39,7 +39,6 @@ exports.createFiberRoot = function(containerInfo : any) : FiberRoot {
containerInfo: containerInfo,
isScheduled: false,
nextScheduledRoot: null,
callbackList: null,
context: null,
pendingContext: null,
};
@@ -59,6 +59,7 @@ export type UpdateQueue = {
first: Update | null,
last: Update | null,
hasForceUpdate: boolean,
callbackList: null | Array<Callback>,
// Dev only
isProcessing?: boolean,
@@ -95,6 +96,7 @@ function ensureUpdateQueue(fiber : Fiber) : UpdateQueue {
first: null,
last: null,
hasForceUpdate: false,
callbackList: null,
isProcessing: false,
};
} else {
@@ -102,6 +104,7 @@ function ensureUpdateQueue(fiber : Fiber) : UpdateQueue {
first: null,
last: null,
hasForceUpdate: false,
callbackList: null,
};
}
@@ -122,6 +125,8 @@ function cloneUpdateQueue(alt : Fiber, fiber : Fiber) : UpdateQueue | null {
altQueue.first = sourceQueue.first;
altQueue.last = sourceQueue.last;
altQueue.hasForceUpdate = sourceQueue.hasForceUpdate;
altQueue.callbackList = sourceQueue.callbackList;
altQueue.isProcessing = sourceQueue.isProcessing;
alt.updateQueue = altQueue;
return altQueue;
}
@@ -438,29 +443,20 @@ function beginUpdateQueue(
// Second condition ignores top-level unmount callbacks if they are not the
// last update in the queue, since a subsequent update will cause a remount.
if (update.callback && !(update.isTopLevelUnmount && update.next)) {
const callbackUpdate = cloneUpdate(update);
if (callbackList && callbackList.last) {
callbackList.last.next = callbackUpdate;
callbackList.last = callbackUpdate;
} else {
callbackList = {
first: callbackUpdate,
last: callbackUpdate,
hasForceUpdate: false,
};
}
callbackList = callbackList || [];
callbackList.push(update.callback);
workInProgress.effectTag |= CallbackEffect;
}
update = update.next;
}
if (!queue.first && !queue.hasForceUpdate) {
// Queue is now empty
queue.callbackList = callbackList;
if (!queue.first && !callbackList && !queue.hasForceUpdate) {
// The queue is empty and there are no callbacks. We can reset it.
workInProgress.updateQueue = null;
}
workInProgress.callbackList = callbackList;
if (__DEV__) {
queue.isProcessing = false;
}
@@ -469,19 +465,14 @@ function beginUpdateQueue(
}
exports.beginUpdateQueue = beginUpdateQueue;
function commitCallbacks(finishedWork : Fiber, callbackList : UpdateQueue, context : mixed) {
const stopAfter = callbackList.last;
let update = callbackList.first;
while (update) {
const callback = update.callback;
if (typeof callback === 'function') {
callback.call(context);
}
if (update === stopAfter) {
break;
}
update = update.next;
function commitCallbacks(finishedWork : Fiber, queue : UpdateQueue, context : mixed) {
const callbackList = queue.callbackList;
if (!callbackList) {
return;
}
for (let i = 0; i < callbackList.length; i++) {
const callback = callbackList[i];
callback.call(context);
}
finishedWork.callbackList = null;
}
exports.commitCallbacks = commitCallbacks;