@samitouri / QOS-React / commits / 56e1c126c5

Move context handling back into Begin and Complete phases

As per discussion, this is better because then this code only runs for the class type of work. We will still need to fix bailouts for deep setState calls.

Dan Abramov committed Nov 14, 2016 at 16:19 UTC 56e1c126c5c29339f8bad4164f8ee510b79a6ea4
3 files changed +25 -23
src/renderers/shared/fiber/ReactFiberBeginWork.js
+16
@@ -27,6 +27,9 @@ var {
27 var ReactTypeOfWork = require('ReactTypeOfWork');
28 var {
29 getMaskedContext,
30 + isContextProvider,
31 + pushContextProvider,
32 + resetContext,
33 } = require('ReactFiberContext');
34 var {
35 IndeterminateComponent,
@@ -195,6 +198,10 @@ module.exports = function<T, P, I, TI, C>(
198 ReactCurrentOwner.current = workInProgress;
199 const nextChildren = instance.render();
200 reconcileChildren(current, workInProgress, nextChildren);
201 + // Put context on the stack because we will work on children
202 + if (isContextProvider(workInProgress)) {
203 + pushContextProvider(workInProgress);
204 + }
205 return workInProgress.child;
206 }
207
@@ -352,6 +359,10 @@ module.exports = function<T, P, I, TI, C>(
359
360 cloneChildFibers(current, workInProgress);
361 markChildAsProgressed(current, workInProgress, priorityLevel);
362 + // Put context on the stack because we will work on children
363 + if (isContextProvider(workInProgress)) {
364 + pushContextProvider(workInProgress);
365 + }
366 return workInProgress.child;
367 }
368
@@ -362,6 +373,11 @@ module.exports = function<T, P, I, TI, C>(
373 }
374
375 function beginWork(current : ?Fiber, workInProgress : Fiber, priorityLevel : PriorityLevel) : ?Fiber {
376 + if (!workInProgress.return) {
377 + // Don't start new work with context on the stack.
378 + resetContext();
379 + }
380 +
381 if (workInProgress.pendingWorkPriority === NoWork ||
382 workInProgress.pendingWorkPriority > priorityLevel) {
383 return bailoutOnLowPriority(current, workInProgress);
src/renderers/shared/fiber/ReactFiberCompleteWork.js
+8
@@ -18,6 +18,10 @@ import type { HostConfig } from 'ReactFiberReconciler';
18 import type { ReifiedYield } from 'ReactReifiedYield';
19
20 var { reconcileChildFibers } = require('ReactChildFiber');
21 +var {
22 + isContextProvider,
23 + popContextProvider,
24 +} = require('ReactFiberContext');
25 var ReactTypeOfWork = require('ReactTypeOfWork');
26 var ReactTypeOfSideEffect = require('ReactTypeOfSideEffect');
27 var {
@@ -125,6 +129,10 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
129 return null;
130 case ClassComponent:
131 transferOutput(workInProgress.child, workInProgress);
132 + // We are leaving this subtree, so pop context if any.
133 + if (isContextProvider(workInProgress)) {
134 + popContextProvider();
135 + }
136 // Don't use the state queue to compute the memoized state. We already
137 // merged it and assigned it to the instance. Transfer it from there.
138 // Also need to transfer the props, because pendingProps will be null
src/renderers/shared/fiber/ReactFiberScheduler.js
+1 -23
@@ -24,13 +24,6 @@ var ReactCurrentOwner = require('ReactCurrentOwner');
24
25 var { cloneFiber } = require('ReactFiber');
26
27 -var {
28 - isContextProvider,
29 - pushContextProvider,
30 - popContextProvider,
31 - resetContext,
32 -} = require('ReactFiberContext');
33 -
27 var {
28 NoWork,
29 SynchronousPriority,
@@ -274,11 +267,6 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
267 const current = workInProgress.alternate;
268 const next = completeWork(current, workInProgress);
269
277 - // We are leaving this subtree, so pop context if any.
278 - if (isContextProvider(workInProgress)) {
279 - popContextProvider();
280 - }
281 -
270 resetWorkPriority(workInProgress);
271
272 // The work is now done. We don't need this anymore. This flags
@@ -357,11 +345,6 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
345 }
346
347 function performUnitOfWork(workInProgress : Fiber) : ?Fiber {
360 - if (!workInProgress.return) {
361 - // Don't start new work with context on the stack.
362 - resetContext();
363 - }
364 -
348 // The current, flushed, state of this fiber is the alternate.
349 // Ideally nothing should rely on this, but relying on it here
350 // means that we don't need an additional field on the work in
@@ -377,12 +360,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
360 ReactFiberInstrumentation.debugTool.onDidBeginWork(workInProgress);
361 }
362
380 - if (next) {
381 - // There is work deeper in the tree, so push the context if it exists.
382 - if (isContextProvider(workInProgress)) {
383 - pushContextProvider(workInProgress);
384 - }
385 - } else {
363 + if (!next) {
364 if (__DEV__ && ReactFiberInstrumentation.debugTool) {
365 ReactFiberInstrumentation.debugTool.onWillCompleteWork(workInProgress);
366 }