Commit Graph
11220 Commits
Author SHA1 Message Date
Andrew Clark a34ca7bce6 [Scheduler] Profiling features (#16145)
* [Scheduler] Mark user-timing events

Marks when Scheduler starts and stops running a task. Also marks when
a task is initially scheduled, and when Scheduler is waiting for a
callback, which can't be inferred from a sample-based JavaScript CPU
profile alone.

The plan is to use the user-timing events to build a Scheduler profiler
that shows how the lifetime of tasks interact with each other and
with unscheduled main thread work.

The test suite works by printing an text representation of a
Scheduler flamegraph.

* Expose shared array buffer with profiling info

Array contains

- the priority Scheduler is currently running
- the size of the queue
- the id of the currently running task

* Replace user-timing calls with event log

Events are written to an array buffer using a custom instruction format.
For now, this is only meant to be used during page start up, before the
profiler worker has a chance to start up. Once the worker is ready, call
`stopLoggingProfilerEvents` to return the log up to that point, then
send the array buffer to the worker.

Then switch to the sampling based approach.

* Record the current run ID

Each synchronous block of Scheduler work is given a unique run ID. This
is different than a task ID because a single task will have more than
one run if it yields with a continuation.
2019-08-13 19:01:17 -07:00
Lee Byron 56636353d8 Partial support for React.lazy() in server renderer. (#16383)
Provides partial support for React.lazy() components from the existing PartialRenderer server-side renderer.

Lazy components which are already resolved (or rejected), perhaps with something like `react-ssr-prepass`, can be continued into synchronously. If they have not yet been initialized, they'll be initialized before checking, opening the possibility to exploit this capability with a babel transform. If they're pending (which will typically be the case for a just initialized async ctor) then the existing invariant continues to be thrown.
2019-08-13 18:51:20 -07:00
Sebastian Markbåge 6fbe630549 [Partial Hydration] Attempt hydration at a higher pri first if props/context changes (#16352)
* Test that we can suspend updates while waiting to hydrate

* Attempt hydration at a higher pri first if props/context changes

* Retrying a dehydrated boundary pings at the earliest forced time

This might quickly become an already expired time.

* Mark the render as delayed if we have to retry

This allows the suspense config to kick in and we can wait for much longer
before we're forced to give up on hydrating.
2019-08-13 18:26:21 -07:00
Dan Abramov e0a521b02a Make component stack last argument for deprecation warnings (#16384) 2019-08-13 23:25:03 +01:00
Dan Abramov 1fd3906e92 Remove "Waiting for async callback" User Timing measurement (#16379)
* Remove "Waiting for async callback" User Timing measurement

* Fix User Timing in PROD mode
2019-08-13 22:03:29 +01:00
lunaruan 89bbffed6e Cleanup Babel PR (ReactFreshPlugin) (#16340)
* fix babel 7 issues

* fix babel 7 issues
2019-08-13 21:18:40 +01:00
Dan Abramov dc3160887b [CI] Disable coverage (#16380)
Looks like it's broken. Don't know if this will work to disable it while we figure out why?
2019-08-13 21:11:51 +01:00
Andrew Clark 21d6395a14 Add test case for #16359 (#16371) 2019-08-12 19:00:50 -07:00
Sebastian Markbåge a29adc9f62 Dehydrated suspense boundaries in suspense list (#16369)
If we get an insertion after a boundary, that has not yet been hydrated,
we take our best guess at which state the HTML is showing.

isSuspenseInstancePending means that we're still waiting for more server
HTML before we can hydrate. This should mean that we're showing the
fallback state.

isSuspenseInstanceFallback means that we want to client render something.
That most likely means that the server was unable to render and is
displaying a fallback state in this slot.

Adds tests to ensure that dehydrated components don't consider the force
flag.
2019-08-12 16:28:02 -07:00
Sebastian Markbåge 50addf4c0e Refactor Partial Hydration (#16346)
* Move dehydrated to be child of regular SuspenseComponent

We now store the comment node on SuspenseState instead and that indicates
that this SuspenseComponent is still dehydrated.

We also store a child but that is only used to represent the DOM node for
deletions and getNextHostSibling.

* Move logic from DehydratedSuspenseComponent to SuspenseComponent

Forked based on SuspenseState.dehydrated instead.

* Retry logic for dehydrated boundary

We can now simplify the logic for retrying dehydrated boundaries without
hydrating. This is becomes simply a reconciliation against the dehydrated
fragment which gets deleted, and the new children gets inserted.

* Remove dehydrated from throw

Instead we use the regular Suspense path. To save code, we attach retry
listeners in the commit phase even though technically we don't have to.

* Pop to nearest Suspense

I think this is right...?

* Popping hydration state should skip past the dehydrated instance

* Split mount from update and special case suspended second pass

The DidCapture flag isn't used consistently in the same way. We need
further refactor for this.

* Reorganize update path

If we remove the dehydration status in the first pass and then do a second
pass because we suspended, then we need to continue as if it didn't
previously suspend. Since there is no fragment child etc.

However, we must readd the deletion.

* Schedule context work on the boundary and not the child

* Warn for Suspense hydration in legacy mode

It does a two pass render that client renders the content.

* Rename DehydratedSuspenseComponent -> DehydratedFragment

This now doesn't represent a suspense boundary itself. Its parent does.

This Fiber represents the fragment around the dehydrated content.

* Refactor returns

Avoids the temporary mutable variables. I kept losing track of them.

* Add a comment explaining the type.

Placing it in the type since that's the central point as opposed to spread
out.
2019-08-12 15:58:38 -07:00
Andrew Clark c2034716a5 Fix typo in error code map (#16373)
"responer" -> "responder"

I also removed an unused error code that never shipped.
2019-08-12 14:56:09 -07:00
Andrew Clark 62b04cfa75 Remove unused import
That's why you wait for the lint job to finish, Andrew!!!!!!
2019-08-12 14:35:33 -07:00
Andrew Clark 3eeb645515 Remove flag that reverts #15650 (#16372)
The change in #15650 has fully rolled out, so we can remove the flag
that reverts it.
2019-08-12 14:31:12 -07:00
Sebastian Markbåge 2716d91ec4 Reset didReceiveUpdate in beginWork (#16359)
This is a bad bug. It means that we sometimes inherit
didReceiveUpdate from a previous component's begin.

Effectively this only means that we're overrendering in some cases.

We should refactor to get rid of this as a global flag.
2019-08-12 14:16:25 -07:00
Nicolas Gallagher 9449f8bf39 [react-events] Fix keyboard responder test (#16368) 2019-08-12 13:51:00 -07:00
Nicolas Gallagher 107521a952 [react-events] Focus/FocusWithin responders with fallbacks (#16343)
Separate the PointerEvent and fallback implementations.
Fix the unit tests to cover both PointerEvent and non-PointerEvent environments.
Fix the focus-visible related callbacks to get called when keys other than "Tab" are used.
2019-08-12 10:10:51 -07:00
Desmond Brand 7a7e792a6f Make SchedulerMinHeap flow strict (#16351)
@acdlite while browsing Twitter, I saw [an opportunity][1] to do
something more productive than browsing Twitter.

[1]: https://twitter.com/acdlite/status/1160247965908234240

Test plan:

`yarn flow-ci`, `yarn test-prod`, `yarn lint`
2019-08-10 13:44:23 -07:00
Andrew Clark e349da19b8 [Scheduler] Temporarily remove wrapper function (#16345)
This code is being compiled incorrectly by something in the Facebook
build pipeline. I'm removing it temporarily to unblock the sync while
we investigate.
2019-08-09 18:08:29 -07:00
Brian Vaughn 5b007573ac Release script supports publishing a subset of packages (#16338)
Release script supports publishing a subset of packages (#16338)
2019-08-09 13:12:00 -07:00
Andrew Clark 0bd0c5269f Upgrade ESLint so we can use JSX Fragment syntax (#16328)
Now that we're using Babel 7, this is the last blocker.
2019-08-09 12:59:02 -07:00
Sebastian Markbåge 07d062dea8 Mark spawned work for client-rendered suspense boundary (#16341)
Currently this is getting marked as Never which is the normal continuation
for a dehydrated boundary, but if it is client-rendered it has a higher
priority. That causes us to drop the interaction tracing for that render.

This colocates the marking where we actually set the expiration time.
2019-08-09 12:37:06 -07:00
Nicolas Gallagher 07a02fb80d [react-events] Refactor unit tests for Hover (#16320)
**Problem**

The existing responders listen to pointer events by default and add fallback events if PointerEvent is not supported. However, this complicates the responders and makes it easy to create a problematic unit test environment. jsdom doesn't support PointerEvent, which means that the responders end up listening to pointer events *and* fallback events in unit tests. This isn't a direct problem in production environments, because no browser will fire pointer events if they aren't supported. But in the unit test environment, we often dispatch event sequences taken from browsers that support pointer events. This means that what we're often testing is actually a (complex) scenario that cannot even occur in production: a responder that is listening to and receives both pointer events and fallback events. Not only does this risk making responders more complicated to implement but it could also hide bugs in implementations.

**Response**

Implement the responders so that they're only listening to *either* pointer events *or* fallback events, never both. This should make the default pointer events implementations significantly simpler and easier to test, as well as free to rely on the complete PointerEvents API. In the future it should also make DCE easier for target environments that are known to support PointerEvents, as we can use build tools with an equivalent of the runtime check. The fallback events (touch and mouse) need to coexist and be resilient to browser emulated events. Our unit tests should express a suite of high-level interactions that can be run in environments with and without PointerEvents support.
2019-08-09 10:53:49 -07:00
Sunil Pai f62b53d908 fix some missing assertions (#16336)
These were discovered by @SimenB in https://github.com/facebook/react/pull/16332. We weren't making actual assertions on some values. This PR makes the assertions, and fixes the tests.
2019-08-09 15:34:49 +01:00
Sunil Pai b9faa3b092 [act] remove obsolete container element (#16312)
In a previous version of act(), we used a dummy dom element to flush effects. This doesn't need to exist anymore, and this PR removes it. The warning doesn't need to be there either (React will fire a wrong renderer act warning if needed).
2019-08-09 14:26:47 +01:00
Sunil Pai 66a474227b use a different link in the UNSAFE_ component warnings (#16321)
When React detects a deprectated/unsafe lifecycle method, the warning points to a page with more details on the why/what of the warning. However, the actual link (https://fb.me/react-async-component-lifecycle-hooks) uses the phrase "lifecycle-hooks" which is confusing since it doesn't have anything to do with hooks. This PR changes the link to something less confusing - https://fb.me/react-unsafe-component-lifecycles.
2019-08-09 12:18:39 +01:00
Brian Vaughn 8d54038773 Add use-subscription to Rollup bundle config (#16326) 2019-08-08 18:52:08 -07:00
b12a982062 Babel 7 (#16297)
Upgraded from Babel 6 to Babel 7.

The only significant change seems to be the way `@babel/plugin-transform-classes` handles classes differently from `babel-plugin-transform-es2015-classes`. In regular mode, the former injects a `_createClass` function that increases the bundle size, and in the latter it removes the safeguard checks. However, this is okay because we don't all classes in new features, and we want to deprecate class usage in the future in the react repo.

Co-authored-by: Luna Ruan <luna@fb.com>
Co-authored-by: Abdul Rauf <abdulraufmujahid@gmail.com>
Co-authored-by: Maksim Markelov <maks-markel@mail.ru>
2019-08-08 17:46:35 -07:00
Andrew Clark d77c6232d3 [Scheduler] Store Tasks on a Min Binary Heap (#16245)
* [Scheduler] Store Tasks on a Min Binary Heap

Switches Scheduler's priority queue implementation (for both tasks and
timers) to an array-based min binary heap.

This replaces the naive linked-list implementation that was left over
from the queue we once used to schedule React roots. A list was arguably
fine when it was only used for roots, since the total number of roots is
usually small, and is only 1 in the common case of a single-page app.

Since Scheduler is now used for many types of JavaScript tasks (e.g.
including timers), the total number of tasks can be much larger.

Binary heaps are the standard way to implement priority queues.
Insertion is O(1) in the average case (append to the end) and O(log n)
in the worst. Deletion is O(log n). Peek is O(1).

* Sophie nits
2019-08-08 16:18:05 -07:00
Andrew Clark 95767acf83 Bump deps in packages/**/package.json (#16325) 2019-08-08 14:50:11 -07:00
Brian Vaughn 6536973a00 Prepare use-subscription v1 for publishing (#16324) 2019-08-08 14:45:48 -07:00
Andrew Clark 85d05b3a4d Bump package.json versions 2019-08-08 14:24:39 -07:00
Dan Abramov 96cdf33ad3 Changelog for 16.9 (#16254)
* Changelog for 16.9 (TODO: add date)

* Update CHANGELOG.md

* Add date
2019-08-08 14:12:59 -07:00
Dominic Gannaway d9fdec6cfe [Flare] Remove contextmenu logic from Press (#16322) 2019-08-08 21:42:01 +01:00
Dan Abramov 12be8938a5 [Fresh] Support multiple renderers at the same time (#16302) 2019-08-08 19:03:38 +01:00
Sebastian Markbåge 6f3c8332d8 Reset hydration state after reentering (#16306)
We might reenter a hydration state, when attempting to hydrate a boundary.
We need to ensure that we reset it to not hydrating once we exit it.
Otherwise the next sibling will still be in hydration mode.
2019-08-07 14:56:12 -07:00
Dominic Gannaway 028c07f89c Ensure Fundamental flags are added to more locations (#16311) 2019-08-07 14:48:30 +01:00
Dan Abramov 9dfe973b52 Nit: fix inconsistent spacing in a warning (#16310) 2019-08-07 14:30:21 +01:00
lunaruan c4f0b93703 Warn when Using String Refs (#16217) 2019-08-07 00:10:19 -07:00
Dominic Gannaway 7c838a6450 [Flare] Adds support for hydrating host components with listeners (#16304) 2019-08-06 23:05:16 +01:00
Nicolas Gallagher ed49700796 [react-events] Separate the Focus/FocusWithin unit tests (#16298) 2019-08-06 09:16:21 -07:00
Nicolas Gallagher 23405c9c4c [react-events] Add ContextMenu responder (#16296)
A module for responding to contextmenu events. This functionality will be
removed from the Press responder in the future.
2019-08-06 09:16:05 -07:00
Sebastian Markbåge 606f76b6e4 Fix hydration bug with nested suspense boundaries (#16288)
This happens in this case: `<!--$!--><!--$!-->...<!--/$--><!--/$-->...`

getNextHydratableInstanceAfterSuspenseInstance didn't take
SUSPENSE_FALLBACK_START_DATA or SUSPENSE_PENDING_START_DATA into account
so if a boundary was in one of those states, it wouldn't be considered to
push the stack of boundaries. As a result the first end comment was
considered the end but it really should've been the second end comment.

The next comment then would've been considered something that can be
skipped. However, since the logic in there considered all comments as
"hydratable", it was considered a hydratable node. Since it was considered
a node that didn't actually correspond to anything in the React tree it got
deleted.

The HTML is now `<!--$!--><!--$!-->...<!--/$-->...` and the trailing
content is now hydrated since it did match something.

Next, since this was client rendered, we're going to delete the suspended
boundary by calling clearSuspenseBoundary and then inserting new content.
However, clearSuspenseBoundary *is* aware of SUSPENSE_FALLBACK_START_DATA
and assumes that there must be another `<!--/$-->` after the first one.
As a result it deleted the trailing content from the DOM since it should
be part of the boundary. However, those DOM nodes were already hydrated in
the React tree. So we end up in an inconsistent state.

When we then try to insert the new content we throw as a result.

I think we would have recovered correctly if clearSuspenseBoundary and
getNextHydratableInstanceAfterSuspenseInstance had the *same* bug but
because they were inconsistent we ended up in a bad place.
2019-08-05 16:36:13 -07:00
Sunil Pai a1dbb852c2 warn if you try to use act() in prod (#16282)
We have behaviour divergence for act() between prod and dev (specifically, act() + concurrent mode does not flush fallbacks in prod. This doesn't affect anyone in OSS yet)

We also don't have a good story for writing tests in prod (and what from what I gather, nobody really writes tests in prod mode).

We could have wiped out act() in prod builds, except that _we_ ourselves use act() for our tests when we run them in prod mode.

This PR is a compromise to all of this. We will log a warning if you try to use act() in prod mode, and we silence it in our test suites.
v16.9.0 v16.9.0-rc.0
2019-08-05 13:01:05 -07:00
Ashwin Ramaswami dc232e6774 chore: remove outdated comment about gcc (#16232) 2019-08-05 18:18:40 +01:00
Andrew Clark 6b565ce736 Rendering tasks should not jump the queue (#16284)
When React schedules a rendering task, it passes a `timeout` option
based on its expiration time. This is intended to avoid starvation
by other React updates. However, it also affects the relative priority
of React tasks and other Scheduler tasks at the same level, like
data processing.

This adds a feature flag to disable passing a `timeout` option to
Scheduler. React tasks will always append themselves to the end of
the queue, without jumping ahead of already scheduled tasks.

This does not affect the order in which React updates within a single
root are processed, but it could affect updates across multiple roots.

This also doesn't remove the expiration from Scheduler. It only means
that React tasks are not given special treatment.
2019-08-02 17:52:32 -07:00
lunaruan c4c9f086eb BugFix: Suspense priority warning firing when not supposed to (#16256)
Previously, the suspense priority warning was fired even if the Root wasn't suspended. Changed the warning to fire only when the root is suspended.

Also refactored the suspense priority warning so it's easier to read.
2019-08-02 13:54:11 -07:00
Andrew Clark 05dce7598a Fix priority of clean-up function on deletion (#16277)
The clean-up function of a passive effect (`useEffect`) usually fires
in a post-commit task, after the browser has painted. However, there is
an exception when the component (or its parent) is deleted from the
tree. In that case, we fire the clean-up function during the
synchronous commit phase, the same phase we use for layout effects.

This is a concession to implementation complexity. Calling it in the
passive effect phase would require either traversing the children of the
deleted fiber again, or including unmount effects as part of the fiber
effect list.

Because the functions are called during the sync phase in this case,
the Scheduler priority is Immediate (the one used for layout) instead
of Normal. We may want to reconsider this trade off later.
2019-08-01 22:17:59 -07:00
Sebastian Markbåge a53f5cc22e [SuspenseList] Bug fix: Reset renderState when bailing out (#16278)
If there are adjacent updates we bail out of rendering the suspense list
at all but we may still complete the node. We need to reset the render
state in that case.

I restructured so that this is in the same code path so we don't forget it
in the future.
2019-08-01 22:02:28 -07:00
Dan Abramov 0c1ec049f8 Add a feature flag to disable legacy context (#16269)
* Add a feature flag to disable legacy context

* Address review

- invariant -> warning
- Make this.context and context argument actually undefined

* Increase test coverage for lifecycles

* Also disable it on the server is flag is on

* Make this.context {} when disabled, but function context is undefined

* Move checks inside
2019-08-02 01:21:32 +01:00
Sebastian Markbåge 95674af2ef Add test of scheduler overhead (#16260) 2019-08-01 17:13:39 -07:00