* Revert "Revert "[Scheduler] Profiling features (#16145)" (#16392)"
This reverts commit 4ba1412305.
* Fix copy paste mistake
* Remove init path dependency on ArrayBuffer
* Add a regression test for cancelling multiple tasks
* Prevent deopt from adding isQueued later
* Remove pop() calls that were added for profiling
* Verify that Suspend/Unsuspend events match up in tests
This currently breaks tests.
* Treat Suspend and Resume as exiting and entering work loop
Their definitions used to be more fuzzy. For example, Suspend didn't always fire on exit, and sometimes fired when we did _not_ exit (such as at task enqueue).
I chatted to Boone, and he's saying treating Suspend and Resume as strictly exiting and entering the loop is fine for their use case.
* Revert "Prevent deopt from adding isQueued later"
This reverts commit 9c30b0b695d81e9c43b296ab93d895e4416ef713.
Unnecessary because GCC
* Start counter with 1
* Group exports into unstable_Profiling namespace
* No catch in PROD codepath
* No label TODO
* No null checks
* [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.
* 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.
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>
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.
- redoes #15431 from scratch, taking on the feedback there
- unifies the messaging between "deprecated" and UNSAFE_ lifecycle messages. It reorganizes ReactStrictModeWarnings.js to capture and flush all the lifecycle warnings in one procedure each.
- matches the warning from ReactPartialRenderer to match the above change
- passes all the tests
- this also turns on `warnAboutDeprecatedLifecycles` for the test renderer. I think we missed doing so it previously. In a future PR, I'll remove the feature flag altogether.
- this DOES NOT do the same treatment for context warnings, I'll do that in another PR too