Skip to content

Commit

Permalink
[scheduler] Remove window.postMessage fallback
Browse files Browse the repository at this point in the history
Every browser we can about supports MessageChannel. The ones we don't
care about will fallback to the setTimeout implementation.
  • Loading branch information
acdlite committed Nov 14, 2018
1 parent 5bce0ef commit 8feeed1
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 47 deletions.
16 changes: 0 additions & 16 deletions packages/react-dom/src/__tests__/ReactDOM-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -450,22 +450,6 @@ describe('ReactDOM', () => {
}
});

it('warns when requestAnimationFrame is not polyfilled', () => {
const previousRAF = global.requestAnimationFrame;
try {
delete global.requestAnimationFrame;
jest.resetModules();
spyOnDevAndProd(console, 'error');
require('react-dom');
expect(console.error.calls.count()).toEqual(1);
expect(console.error.calls.argsFor(0)[0]).toMatch(
"This browser doesn't support requestAnimationFrame.",
);
} finally {
global.requestAnimationFrame = previousRAF;
}
});

it('reports stacks with re-entrant renderToString() calls on the client', () => {
function Child2(props) {
return <span ariaTypo3="no">{props.children}</span>;
Expand Down
36 changes: 7 additions & 29 deletions packages/scheduler/src/Scheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,8 @@ if (typeof window !== 'undefined' && window._schedMock) {
// If Scheduler runs in a non-DOM environment, it falls back to a naive
// implementation using setTimeout.
typeof window === 'undefined' ||
// "addEventListener" might not be available on the window object
// if this is a mocked "window" object. So we need to validate that too.
typeof window.addEventListener !== 'function'
// Check if MessageChannel is supported, too.
typeof MessageChannel !== 'function'
) {
var _callback = null;
var _currentTime = -1;
Expand Down Expand Up @@ -533,17 +532,9 @@ if (typeof window !== 'undefined' && window._schedMock) {
};

// We use the postMessage trick to defer idle work until after the repaint.
var port = null;
var messageKey =
'__reactIdleCallback$' +
Math.random()
.toString(36)
.slice(2);
var idleTick = function(event) {
if (event.source !== port || event.data !== messageKey) {
return;
}

var channel = new MessageChannel();
var port = channel.port2;
channel.port1.onmessage = function(event) {
isMessageEventScheduled = false;

var prevScheduledCallback = scheduledHostCallback;
Expand Down Expand Up @@ -627,7 +618,7 @@ if (typeof window !== 'undefined' && window._schedMock) {
frameDeadline = rafTime + activeFrameTime;
if (!isMessageEventScheduled) {
isMessageEventScheduled = true;
port.postMessage(messageKey, '*');
port.postMessage('*');
}
};

Expand All @@ -636,7 +627,7 @@ if (typeof window !== 'undefined' && window._schedMock) {
timeoutTime = absoluteTimeout;
if (isFlushingHostCallback || absoluteTimeout < 0) {
// Don't wait for the next frame. Continue working ASAP, in a new event.
port.postMessage(messageKey, '*');
port.postMessage('*');
} else if (!isAnimationFrameScheduled) {
// If rAF didn't already schedule one, we need to schedule a frame.
// TODO: If this rAF doesn't materialize because the browser throttles, we
Expand All @@ -647,19 +638,6 @@ if (typeof window !== 'undefined' && window._schedMock) {
}
};

if (typeof MessageChannel === 'function') {
// Use a MessageChannel, if support exists
var channel = new MessageChannel();
channel.port1.onmessage = idleTick;
port = channel.port2;
} else {
// Otherwise post a message to the window. This isn't ideal because message
// handlers will fire on every frame until the queue is empty, including
// some browser extensions.
window.addEventListener('message', idleTick, false);
port = window;
}

cancelHostCallback = function() {
scheduledHostCallback = null;
isMessageEventScheduled = false;
Expand Down
2 changes: 1 addition & 1 deletion packages/scheduler/src/__tests__/SchedulerDOM-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ describe('SchedulerDOM', () => {
this.port1 = port1;
this.port2 = port2;
};
postMessageCallback = event => port1.onmessage(event);
postMessageCallback = () => port1.onmessage();
global.Date.now = function() {
return currentTime;
};
Expand Down
10 changes: 9 additions & 1 deletion packages/shared/__tests__/ReactDOMFrameScheduling-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@
describe('ReactDOMFrameScheduling', () => {
it('warns when requestAnimationFrame is not polyfilled in the browser', () => {
const previousRAF = global.requestAnimationFrame;
const previousMessageChannel = global.MessageChannel;
try {
global.requestAnimationFrame = undefined;
delete global.requestAnimationFrame;
global.MessageChannel = function MessageChannel() {
return {
port1: {},
port2: {},
};
};
jest.resetModules();
spyOnDevAndProd(console, 'error');
require('react-dom');
Expand All @@ -22,6 +29,7 @@ describe('ReactDOMFrameScheduling', () => {
"This browser doesn't support requestAnimationFrame.",
);
} finally {
global.MessageChannel = previousMessageChannel;
global.requestAnimationFrame = previousRAF;
}
});
Expand Down

0 comments on commit 8feeed1

Please sign in to comment.