Skip to content

Commit

Permalink
Re-add discrete flushing timeStamp heuristic
Browse files Browse the repository at this point in the history
Re-add discrete flushing timeStamp heuristic

Re-add discrete flushing timeStamp heuristic
  • Loading branch information
trueadm committed Aug 5, 2020
1 parent 5cff775 commit 23a390c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/react-dom/src/events/ReactDOMEventListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function dispatchDiscreteEvent(
// flushed for this event and we don't need to do it again.
(eventSystemFlags & IS_LEGACY_FB_SUPPORT_MODE) === 0
) {
flushDiscreteUpdatesIfNeeded();
flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
}
discreteUpdates(
dispatchEvent,
Expand Down
25 changes: 23 additions & 2 deletions packages/react-dom/src/events/ReactDOMUpdateBatching.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
restoreStateIfNeeded,
} from './ReactDOMControlledComponent';

import {enableDeprecatedFlareAPI} from 'shared/ReactFeatureFlags';

// Used as a way to call batchedUpdates when we don't have a reference to
// the renderer. Such as when we're dispatching events or if third party
// libraries need to call batchedUpdates. Eventually, this API will go away when
Expand Down Expand Up @@ -87,8 +89,27 @@ export function discreteUpdates(fn, a, b, c, d) {
}
}

export function flushDiscreteUpdatesIfNeeded() {
if (!isInsideEventHandler) {
let lastFlushedEventTimeStamp = 0;
export function flushDiscreteUpdatesIfNeeded(timeStamp: number) {
// event.timeStamp isn't overly reliable due to inconsistencies in
// how different browsers have historically provided the time stamp.
// Some browsers provide high-resolution time stamps for all events,
// some provide low-resolution time stamps for all events. FF < 52
// even mixes both time stamps together. Some browsers even report
// negative time stamps or time stamps that are 0 (iOS9) in some cases.
// Given we are only comparing two time stamps with equality (!==),
// we are safe from the resolution differences. If the time stamp is 0
// we bail-out of preventing the flush, which can affect semantics,
// such as if an earlier flush removes or adds event listeners that
// are fired in the subsequent flush. However, this is the same
// behaviour as we had before this change, so the risks are low.
if (
!isInsideEventHandler &&
(!enableDeprecatedFlareAPI ||
timeStamp === 0 ||
lastFlushedEventTimeStamp !== timeStamp)
) {
lastFlushedEventTimeStamp = timeStamp;
flushDiscreteUpdatesImpl();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,16 +229,12 @@ describe('SimpleEventPlugin', function() {
});

describe('interactive events, in concurrent mode', () => {
beforeEach(() => {
// @gate experimental
it('flushes pending interactive work before extracting event handler', () => {
jest.resetModules();

React = require('react');
ReactDOM = require('react-dom');
Scheduler = require('scheduler');
});

// @gate experimental
it('flushes pending interactive work before extracting event handler', () => {
container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
document.body.appendChild(container);
Expand Down

0 comments on commit 23a390c

Please sign in to comment.