Skip to content

Commit 8feeed1

Browse files
committedNov 14, 2018
[scheduler] Remove window.postMessage fallback
Every browser we can about supports MessageChannel. The ones we don't care about will fallback to the setTimeout implementation.
1 parent 5bce0ef commit 8feeed1

File tree

4 files changed

+17
-47
lines changed

4 files changed

+17
-47
lines changed
 

‎packages/react-dom/src/__tests__/ReactDOM-test.js

-16
Original file line numberDiff line numberDiff line change
@@ -450,22 +450,6 @@ describe('ReactDOM', () => {
450450
}
451451
});
452452

453-
it('warns when requestAnimationFrame is not polyfilled', () => {
454-
const previousRAF = global.requestAnimationFrame;
455-
try {
456-
delete global.requestAnimationFrame;
457-
jest.resetModules();
458-
spyOnDevAndProd(console, 'error');
459-
require('react-dom');
460-
expect(console.error.calls.count()).toEqual(1);
461-
expect(console.error.calls.argsFor(0)[0]).toMatch(
462-
"This browser doesn't support requestAnimationFrame.",
463-
);
464-
} finally {
465-
global.requestAnimationFrame = previousRAF;
466-
}
467-
});
468-
469453
it('reports stacks with re-entrant renderToString() calls on the client', () => {
470454
function Child2(props) {
471455
return <span ariaTypo3="no">{props.children}</span>;

‎packages/scheduler/src/Scheduler.js

+7-29
Original file line numberDiff line numberDiff line change
@@ -457,9 +457,8 @@ if (typeof window !== 'undefined' && window._schedMock) {
457457
// If Scheduler runs in a non-DOM environment, it falls back to a naive
458458
// implementation using setTimeout.
459459
typeof window === 'undefined' ||
460-
// "addEventListener" might not be available on the window object
461-
// if this is a mocked "window" object. So we need to validate that too.
462-
typeof window.addEventListener !== 'function'
460+
// Check if MessageChannel is supported, too.
461+
typeof MessageChannel !== 'function'
463462
) {
464463
var _callback = null;
465464
var _currentTime = -1;
@@ -533,17 +532,9 @@ if (typeof window !== 'undefined' && window._schedMock) {
533532
};
534533

535534
// We use the postMessage trick to defer idle work until after the repaint.
536-
var port = null;
537-
var messageKey =
538-
'__reactIdleCallback$' +
539-
Math.random()
540-
.toString(36)
541-
.slice(2);
542-
var idleTick = function(event) {
543-
if (event.source !== port || event.data !== messageKey) {
544-
return;
545-
}
546-
535+
var channel = new MessageChannel();
536+
var port = channel.port2;
537+
channel.port1.onmessage = function(event) {
547538
isMessageEventScheduled = false;
548539

549540
var prevScheduledCallback = scheduledHostCallback;
@@ -627,7 +618,7 @@ if (typeof window !== 'undefined' && window._schedMock) {
627618
frameDeadline = rafTime + activeFrameTime;
628619
if (!isMessageEventScheduled) {
629620
isMessageEventScheduled = true;
630-
port.postMessage(messageKey, '*');
621+
port.postMessage('*');
631622
}
632623
};
633624

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

650-
if (typeof MessageChannel === 'function') {
651-
// Use a MessageChannel, if support exists
652-
var channel = new MessageChannel();
653-
channel.port1.onmessage = idleTick;
654-
port = channel.port2;
655-
} else {
656-
// Otherwise post a message to the window. This isn't ideal because message
657-
// handlers will fire on every frame until the queue is empty, including
658-
// some browser extensions.
659-
window.addEventListener('message', idleTick, false);
660-
port = window;
661-
}
662-
663641
cancelHostCallback = function() {
664642
scheduledHostCallback = null;
665643
isMessageEventScheduled = false;

‎packages/scheduler/src/__tests__/SchedulerDOM-test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ describe('SchedulerDOM', () => {
8383
this.port1 = port1;
8484
this.port2 = port2;
8585
};
86-
postMessageCallback = event => port1.onmessage(event);
86+
postMessageCallback = () => port1.onmessage();
8787
global.Date.now = function() {
8888
return currentTime;
8989
};

‎packages/shared/__tests__/ReactDOMFrameScheduling-test.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,15 @@
1212
describe('ReactDOMFrameScheduling', () => {
1313
it('warns when requestAnimationFrame is not polyfilled in the browser', () => {
1414
const previousRAF = global.requestAnimationFrame;
15+
const previousMessageChannel = global.MessageChannel;
1516
try {
16-
global.requestAnimationFrame = undefined;
17+
delete global.requestAnimationFrame;
18+
global.MessageChannel = function MessageChannel() {
19+
return {
20+
port1: {},
21+
port2: {},
22+
};
23+
};
1724
jest.resetModules();
1825
spyOnDevAndProd(console, 'error');
1926
require('react-dom');
@@ -22,6 +29,7 @@ describe('ReactDOMFrameScheduling', () => {
2229
"This browser doesn't support requestAnimationFrame.",
2330
);
2431
} finally {
32+
global.MessageChannel = previousMessageChannel;
2533
global.requestAnimationFrame = previousRAF;
2634
}
2735
});

0 commit comments

Comments
 (0)
Please sign in to comment.