* 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 9c30b0b695.
Unnecessary because GCC
* Start counter with 1
* Group exports into unstable_Profiling namespace
* No catch in PROD codepath
* No label TODO
* No null checks
* Refactor a bit to use less property access
* Add test for invoking an event before mount
* Add Hydration effect tag
This is equivalent to a "Placement" effect in that it's a new insertion
to the tree but it doesn't need an actual mutation.
It is only used to determine if a subtree has actually mounted yet.
* Use the Hydration flag for Roots
Previous roots had a Placement flag on them as a hack for this case but
since we have a special flag for it now, we can just use that.
* Add Flare test
The semantics of 'button' on events differs between PointerEvent and
MouseEvent, whereas they are the same for 'buttons'. Furthermore, 'buttons'
allows developers to determine when multiple buttons are pressed as the same
time.
https://w3c.github.io/pointerevents/#the-button-property
* Add a way to skip/only tests to RulesOfHooks test
* [ESLint] Forbid top-level use*() calls
* Add a regression test for logical expressions
This is not a change. Just adding more coverage.
This patch formalizes the mock native events and event sequences used in unit tests.
The `createEventTarget` function returns an object that can be used to dispatch native event sequences on the target without having to manually do so across all the scenarios we need to account for. Unit tests can be written as if we were only working with PointerEvent, but they will dispatch realistic native event sequences based on the execution environment (e.g., is PointerEvent supported?) and pointer type.
```
describe.each(environments)('Suite', (hasPointerEvents) => {
beforeEach(() => {
// setup
});
test.each(pointerTypes)('Test', (pointerType) => {
const target = createEventTarget(node);
target.pointerdown({pointerType});
expect(callback).toBeCalled();
});
});
```
Every native event that is dispatched now includes a complete object by default. The properties of the events can be customized. Properties that shouldn't be relied on in responder implementations are excluded from the mock native events to ensure tests will fail. Equivalent properties are normalized across different event types, e.g., 'pointerId' is converted to 'identifier' before a TouchEvent is dispatched.
1. Run the tests in both an environment without PointerEvent and one with PointerEvent.
2. Improve test coverage to include both mouse and touch pointers.
3. Change 'Press' so that it only listens to either pointer events or fallbacks events.
* Fixed issue with def being undefined while referencing arguments.
* Removed todo comment.
* Skip exhaustive deps check if def is null.
* Fixed code formatting in ExhaustiveDeps.
* Removed unneeded comment in ExhaustiveDeps.
* [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.
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.
* 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.
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.