Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 42 additions & 39 deletions fixtures/fiber-triangle/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,51 +76,54 @@ <h1>Fiber Example</h1>
}
}

function SierpinskiTriangle({ x, y, s, children }) {
if (s <= targetSize) {
return (
<Dot
x={x - (targetSize / 2)}
y={y - (targetSize / 2)}
size={targetSize}
text={children}
/>
class SierpinskiTriangle extends React.Component {
shouldComponentUpdate(nextProps) {
var o = this.props;
var n = nextProps;
return !(
o.x === n.x &&
o.y === n.y &&
o.s === n.s &&
o.children === n.children
);
return r;
}
var newSize = s / 2;
var slowDown = true;
if (slowDown) {
var e = performance.now() + 0.8;
while (performance.now() < e) {
// Artificially long execution time.
render() {
let {x, y, s, children} = this.props;
if (s <= targetSize) {
return (
<Dot
x={x - (targetSize / 2)}
y={y - (targetSize / 2)}
size={targetSize}
text={children}
/>
);
return r;
}
var newSize = s / 2;
var slowDown = true;
if (slowDown) {
var e = performance.now() + 0.8;
while (performance.now() < e) {
// Artificially long execution time.
}
}
}

s /= 2;
s /= 2;

return [
<SierpinskiTriangle x={x} y={y - (s / 2)} s={s}>
{children}
</SierpinskiTriangle>,
<SierpinskiTriangle x={x - s} y={y + (s / 2)} s={s}>
{children}
</SierpinskiTriangle>,
<SierpinskiTriangle x={x + s} y={y + (s / 2)} s={s}>
{children}
</SierpinskiTriangle>,
];
return [
<SierpinskiTriangle x={x} y={y - (s / 2)} s={s}>
{children}
</SierpinskiTriangle>,
<SierpinskiTriangle x={x - s} y={y + (s / 2)} s={s}>
{children}
</SierpinskiTriangle>,
<SierpinskiTriangle x={x + s} y={y + (s / 2)} s={s}>
{children}
</SierpinskiTriangle>,
];
}
}
SierpinskiTriangle.shouldComponentUpdate = function(oldProps, newProps) {
var o = oldProps;
var n = newProps;
return !(
o.x === n.x &&
o.y === n.y &&
o.s === n.s &&
o.children === n.children
);
};

class ExampleApplication extends React.Component {
constructor() {
Expand Down
2 changes: 2 additions & 0 deletions src/renderers/art/ReactARTFiberEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@ const ARTRenderer = ReactFiberReconciler({
);
},

now: ReactDOMFrameScheduling.now,

useSyncScheduling: true,
});

Expand Down
2 changes: 2 additions & 0 deletions src/renderers/dom/fiber/ReactDOMFiberEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,8 @@ var DOMRenderer = ReactFiberReconciler({
}
},

now: ReactDOMFrameScheduling.now,

canHydrateInstance(
instance: Instance | TextInstance,
type: string,
Expand Down
5 changes: 5 additions & 0 deletions src/renderers/native-rt/ReactNativeRTFiberRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ const NativeRTRenderer = ReactFiberReconciler({
},

useSyncScheduling: true,

now(): number {
// TODO: Enable expiration by implementing this method.
return 0;
},
});

module.exports = NativeRTRenderer;
5 changes: 5 additions & 0 deletions src/renderers/native/ReactNativeFiberRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ const NativeRenderer = ReactFiberReconciler({
},

useSyncScheduling: true,

now(): number {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this added to ReactNativeFiberRenderer and not ReactNativeFiberEntry?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Entry" modules are the public API. The renderer is what you create out of a host config. For whatever reason, our React Native renderer splits the two into separate files, whereas our DOM renderer does not. Don't think there's any real reason, just happened to be factored that way.

// TODO: Enable expiration by implementing this method.
return 0;
},
});

module.exports = NativeRenderer;
20 changes: 17 additions & 3 deletions src/renderers/noop/ReactNoopEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ function removeChild(
parentInstance.children.splice(index, 1);
}

let elapsedTimeInMs = 0;

var NoopRenderer = ReactFiberReconciler({
getRootHostContext() {
if (failInBeginPhase) {
Expand Down Expand Up @@ -201,6 +203,10 @@ var NoopRenderer = ReactFiberReconciler({
prepareForCommit(): void {},

resetAfterCommit(): void {},

now(): number {
return elapsedTimeInMs;
},
});

var rootContainers = new Map();
Expand Down Expand Up @@ -336,6 +342,14 @@ var ReactNoop = {
expect(actual).toEqual(expected);
},

expire(ms: number): void {
elapsedTimeInMs += ms;
},

flushExpired(): Array<mixed> {
return ReactNoop.flushUnitsOfWork(0);
},

yield(value: mixed) {
if (yieldedValues === null) {
yieldedValues = [value];
Expand Down Expand Up @@ -400,15 +414,15 @@ var ReactNoop = {
' '.repeat(depth + 1) + '~',
firstUpdate && firstUpdate.partialState,
firstUpdate.callback ? 'with callback' : '',
'[' + firstUpdate.priorityLevel + ']',
'[' + firstUpdate.expirationTime + ']',
);
var next;
while ((next = firstUpdate.next)) {
log(
' '.repeat(depth + 1) + '~',
next.partialState,
next.callback ? 'with callback' : '',
'[' + firstUpdate.priorityLevel + ']',
'[' + firstUpdate.expirationTime + ']',
);
}
}
Expand All @@ -418,7 +432,7 @@ var ReactNoop = {
' '.repeat(depth) +
'- ' +
(fiber.type ? fiber.type.name || fiber.type : '[root]'),
'[' + fiber.pendingWorkPriority + (fiber.pendingProps ? '*' : '') + ']',
'[' + fiber.expirationTime + (fiber.pendingProps ? '*' : '') + ']',
);
if (fiber.updateQueue) {
logUpdateQueue(fiber.updateQueue, depth);
Expand Down
45 changes: 32 additions & 13 deletions src/renderers/shared/ReactDOMFrameScheduling.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@ if (__DEV__) {
}
}

const hasNativePerformanceNow =
typeof performance === 'object' && typeof performance.now === 'function';

let now;
if (hasNativePerformanceNow) {
now = function() {
return performance.now();
};
} else {
now = function() {
return Date.now();
};
}

// TODO: There's no way to cancel, because Fiber doesn't atm.
let rIC: (callback: (deadline: Deadline) => void) => number;

Expand Down Expand Up @@ -67,19 +81,23 @@ if (!ExecutionEnvironment.canUseDOM) {
var previousFrameTime = 33;
var activeFrameTime = 33;

var frameDeadlineObject = {
timeRemaining: typeof performance === 'object' &&
typeof performance.now === 'function'
? function() {
// We assume that if we have a performance timer that the rAF callback
// gets a performance timer value. Not sure if this is always true.
return frameDeadline - performance.now();
}
: function() {
// As a fallback we use Date.now.
return frameDeadline - Date.now();
},
};
var frameDeadlineObject;
if (hasNativePerformanceNow) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we do the judgement again instead calling now() directly?

frameDeadlineObject = {
timeRemaining() {
// We assume that if we have a performance timer that the rAF callback
// gets a performance timer value. Not sure if this is always true.
return frameDeadline - performance.now();
},
};
} else {
frameDeadlineObject = {
timeRemaining() {
// Fallback to Date.now()
return frameDeadline - Date.now();
},
};
}

// We use the postMessage trick to defer idle work until after the repaint.
var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2);
Expand Down Expand Up @@ -153,4 +171,5 @@ if (!ExecutionEnvironment.canUseDOM) {
rIC = requestIdleCallback;
}

exports.now = now;
exports.rIC = rIC;
Loading