Add areChildrenOffscreen to host config
Renderers can determine whether a node's children are offscreen based on the host component's props. If so, they are given OffscreenPriority. useSyncScheduling takes precedence.
Andrew Clark committed
Feb 27, 2017 at 16:57 UTC
4602e768f3a65f8076d70aa67b8a7c94d7cc377f
7 files changed
+26
-4
src/renderers/art/ReactARTFiber.js
+4
@@ -503,6 +503,10 @@ const ARTRenderer = ReactFiberReconciler({
503
// Noop
504
},
505
506
+ areChildrenOffscreen(props : Props) {
507
+ return false;
508
+ },
509
+
510
getRootHostContext() {
511
return emptyObject;
512
},
src/renderers/dom/fiber/ReactDOMFiber.js
+5
@@ -69,6 +69,7 @@ type Container = Element;
69
type Props = {
70
autoFocus ?: boolean,
71
children ?: mixed,
72
+ hidden ?: boolean,
73
};
74
type Instance = Element;
75
type TextInstance = Text;
@@ -286,6 +287,10 @@ var DOMRenderer = ReactFiberReconciler({
287
domElement.textContent = '';
288
},
289
290
+ areChildrenOffscreen(props : Props) : boolean {
291
+ return Boolean(props.hidden);
292
+ },
293
+
294
createTextInstance(
295
text : string,
296
rootContainerInstance : Container,
src/renderers/native/ReactNativeFiber.js
+4
@@ -343,6 +343,10 @@ const NativeRenderer = ReactFiberReconciler({
343
// Noop
344
},
345
346
+ areChildrenOffscreen(props : Props) : boolean {
347
+ return false;
348
+ },
349
+
350
scheduleAnimationCallback: global.requestAnimationFrame,
351
352
scheduleDeferredCallback: global.requestIdleCallback,
src/renderers/noop/ReactNoop.js
+5
-1
@@ -35,7 +35,7 @@ var scheduledAnimationCallback = null;
35
var scheduledDeferredCallback = null;
36
37
type Container = { rootID: string, children: Array<Instance | TextInstance> };
38
-type Props = { prop: any };
38
+type Props = { prop: any, hidden ?: boolean };
39
type Instance = {| type: string, id: number, children: Array<Instance | TextInstance>, prop: any |};
40
type TextInstance = {| text: string, id: number |};
41
@@ -101,6 +101,10 @@ var NoopRenderer = ReactFiberReconciler({
101
102
resetTextContent(instance : Instance) : void {},
103
104
+ areChildrenOffscreen(props : Props) : boolean {
105
+ return Boolean(props.hidden);
106
+ },
107
+
108
createTextInstance(
109
text : string,
110
rootContainerInstance : Container,
src/renderers/shared/fiber/ReactFiberBeginWork.js
+3
-3
@@ -77,7 +77,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
77
getPriorityContext : () => PriorityLevel,
78
) {
79
80
- const { shouldSetTextContent, useSyncScheduling } = config;
80
+ const { shouldSetTextContent, useSyncScheduling, areChildrenOffscreen } = config;
81
82
const {
83
pushHostContext,
@@ -358,7 +358,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
358
}
359
} else if (nextProps === null || memoizedProps === nextProps) {
360
if (!useSyncScheduling &&
361
- memoizedProps.hidden &&
361
+ areChildrenOffscreen(memoizedProps) &&
362
workInProgress.pendingWorkPriority !== OffscreenPriority) {
363
// This subtree still has work, but it should be deprioritized so we need
364
// to bail out and not do any work yet.
@@ -400,7 +400,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
400
markRef(current, workInProgress);
401
402
if (!useSyncScheduling &&
403
- nextProps.hidden &&
403
+ areChildrenOffscreen(nextProps) &&
404
workInProgress.pendingWorkPriority !== OffscreenPriority) {
405
// If this host component is hidden, we can bail out on the children.
406
// We'll rerender the children later at the lower priority.
src/renderers/shared/fiber/ReactFiberReconciler.js
+1
@@ -83,6 +83,7 @@ export type HostConfig<T, P, I, TI, PI, C, CX, PL> = {
83
84
shouldSetTextContent(props : P) : boolean,
85
resetTextContent(instance : I) : void,
86
+ areChildrenOffscreen(props : P) : boolean,
87
88
createTextInstance(
89
text : string,
src/renderers/testing/ReactTestRendererFiber.js
+4
@@ -150,6 +150,10 @@ var TestRenderer = ReactFiberReconciler({
150
// noop
151
},
152
153
+ areChildrenOffscreen(props : Props) : boolean {
154
+ return false;
155
+ },
156
+
157
createTextInstance(
158
text : string,
159
rootContainerInstance : Container,