Commit Graph

880 Commits

Author SHA1 Message Date
poteto 877636d7e9 [rcr] Re-export useMemoCache in top level React namespace (#31139)
In order to support using the compiler on versions of React prior to 19,
we need the ability to statically import `c` (aka useMemoCache) or
fallback to a polyfill supplied by `react-compiler-runtime` (note: this
is a separate npm package, not to be confused with
`react/compiler-runtime`, which is currently a part of react).

To do this we first need to re-export `useMemoCache` under the top level
React namespace again, which is additive and thus non-breaking. Doing so
allows `react-compiler-runtime` to statically either re-export
`React.__COMPILER_RUNTIME.c` or supply a polyfill, without the need for
a dynamic import which is finicky to support due to returning a promise.

In later PRs I will remove `react/compiler-runtime` and update the
compiler to emit imports to `react-compiler-runtime` instead.

DiffTrain build for [b78a7f2f35](https://github.com/facebook/react/commit/b78a7f2f35e554a8647c3262d7f392e68d06febc)
2024-10-07 13:32:14 -07:00
jackpope 56bda35dd1 Disable infinite render loop detection (#31088)
We're seeing issues with this feature internally including bugs with
sibling prerendering and errors that are difficult for developers to
action on. We'll turn off the feature for the time being until we can
improve the stability and ergonomics.

This PR does two things:
- Turn off `enableInfiniteLoopDetection` everywhere while leaving it as
a variant on www so we can do further experimentation.
- Revert https://github.com/facebook/react/pull/31061 which was a
temporary change for debugging. This brings the feature back to
baseline.

DiffTrain build for [d8c90fa48d](https://github.com/facebook/react/commit/d8c90fa48d3addefe4b805ec56a3c65e4ee39127)
2024-10-01 08:08:39 -07:00
gnoff e2de2adf75 [Fizz] Start initial work immediately (#31079)
In a recent update we make Flight start working immediately rather than
waitin for a new task. This commit updates fizz to have similar
mechanics. We start the render in the currently running task but we do
so in a microtask to avoid reentrancy. This aligns Fizz with Flight.

ref: https://github.com/facebook/react/pull/30961

DiffTrain build for [67fee58b1f](https://github.com/facebook/react/commit/67fee58b1f72754cc77488c40c44e786572ef954)
2024-09-26 13:59:31 -07:00
poteto b113f683d4 No commit message
DiffTrain build for [67fee58b1f](https://github.com/facebook/react/commit/67fee58b1f72754cc77488c40c44e786572ef954)
2024-09-26 13:58:44 -07:00
eps1lon 5f9db2fb7f [Fiber] Fix missing render times when we cancel a pending commit (#31065)
DiffTrain build for [778e1ed2e5](https://github.com/facebook/react/commit/778e1ed2e5ec22d4bac48e14167d3b4a6b28e8b8)
2024-09-25 15:28:49 -07:00
acdlite 9b61452a2a Make prerendering always non-blocking (#31056)
When a synchronous update suspends, and we prerender the siblings, the
prerendering should be non-blocking so that we can immediately restart
once the data arrives.

This happens automatically when there's a Suspense boundary, because we
immediately commit the boundary and then proceed to a Retry render,
which are always concurrent. When there's not a Suspense boundary, there
is no Retry, so we need to take care to switch from the synchronous work
loop to the concurrent one, to enable time slicing.

DiffTrain build for [0f1856c49f](https://github.com/facebook/react/commit/0f1856c49febe96923e469f98c0b123130ea015c)
2024-09-25 13:40:14 -07:00
acdlite fd6224b6ea Unify perform{Sync,Concurrent}WorkOnRoot implementation (#31029)
Over time the behavior of these two paths has converged to be
essentially the same. So this merges them back into one function. This
should save some code size and also make it harder for the behavior to
accidentally diverge. (For the same reason, rolling out this change
might expose some areas where we had already accidentally diverged.)

DiffTrain build for [3c7667a694](https://github.com/facebook/react/commit/3c7667a694face1827356a7c90ee6f86a9c0baa0)
2024-09-25 12:41:50 -07:00
jackpope f1486377de Increase nested update limit to 100 (#31061)
We're seeing the limit hit in some tests after enabling sibling
prerendering. Let's bump the limit so we can run more tests and gather
more signal on the changes. When we understand the scope of the problem
we can determine whether we need to change how the updates are counted
in prerenders and/or fix specific areas of product code.

DiffTrain build for [f9ebd85a19](https://github.com/facebook/react/commit/f9ebd85a196948be17efdd6774b4d0464b3b1f53)
2024-09-25 08:59:35 -07:00
poteto 97355e033b DiffTrain build for [](https://github.com/facebook/react/commit/) 2024-09-24 09:00:02 -07:00
sebmarkbage d21a7619e0 [Fiber] Log the Render/Commit phases and the gaps in between (#31016)
A slight behavior change here too is that I now mark the start of the
commit phase before the BeforeMutationEffect phase. This affects
`<Profiler>` too.

The named sequences are as follows:

Render -> Suspended or Throttled -> Commit -> Waiting for Paint ->
Remaining Effects

The Suspended phase is only logged if we delay the Commit due to CSS /
images.

The Throttled phase is only logged if we delay the commit due to the
Suspense throttling timer.

<img width="1246" alt="Screenshot 2024-09-20 at 9 14 23 PM"
src="https://github.com/user-attachments/assets/8d01f444-bb85-472b-9b42-6157d92c81b4">

I don't yet log render phases that don't complete. I think I also need
to special case renders that or don't commit after being suspended.

DiffTrain build for [4e9540e3c2](https://github.com/facebook/react/commit/4e9540e3c2a8f9ae56318b967939c99b3a815190)
2024-09-23 11:17:21 -07:00
sebmarkbage 7e85a93c6d [Fiber] Track Event Time, startTransition Time and setState Time (#31008)
This tracks the current window.event.timeStamp the first time we
setState or call startTransition. For either the blocking track or
transition track. We can use this to show how long we were blocked by
other events or overhead from when the user interacted until we got
called into React.

Then we track the time we start awaiting a Promise returned from
startTransition. We can use this track how long we waited on an Action
to complete before setState was called.

Then finally we track when setState was called so we can track how long
we were blocked by other word before we could actually start rendering.
For a Transition this might be blocked by Blocking React render work.

We only log these once a subsequent render actually happened. If no
render was actually scheduled, then we don't log these. E.g. if an
isomorphic Action doesn't call startTransition there's no render so we
don't log it.

We only log the first event/update/transition even if multiple are
batched into it later. If multiple Actions are entangled they're all
treated as one until an update happens. If no update happens and all
entangled actions finish, we clear the transition so that the next time
a new sequence starts we can log it.

We also clamp these (start the track later) if they were scheduled
within a render/commit. Since we share a single track we don't want to
create overlapping tracks.

The purpose of this is not to show every event/action that happens but
to show a prelude to how long we were blocked before a render started.
So you can follow the first event to commit.

<img width="674" alt="Screenshot 2024-09-20 at 1 59 58 AM"
src="https://github.com/user-attachments/assets/151ba9e8-6b3c-4fa1-9f8d-e3602745eeb7">

I still need to add the rendering/suspended phases to the timeline which
why this screenshot has a gap.

<img width="993" alt="Screenshot 2024-09-20 at 12 50 27 AM"
src="https://github.com/user-attachments/assets/155b6675-b78a-4a22-a32b-212c15051074">

In this case it's a Form Action which started a render into the form
which then suspended on the action. The action then caused a refresh,
which interrupts with its own update that's blocked before rendering.
Suspended roots like this is interesting because we could in theory
start working on a different root in the meantime which makes this
timeline less linear.

DiffTrain build for [d4688dfaaf](https://github.com/facebook/react/commit/d4688dfaafe51a4cb6e3c51fc2330662cb4e2296)
2024-09-20 11:34:59 -07:00
gnoff fe28b5dd9a [Fizz] Include componentStack at the root when aborting (#31011)
When aborting we currently don't produce a componentStack when aborting
the shell. This is likely just an oversight and this change updates this
behavior to be consistent with what we do when there is a boundary

DiffTrain build for [ae75d5a3f5](https://github.com/facebook/react/commit/ae75d5a3f5cf14a5031ee251376b1adf88c32813)
2024-09-20 10:07:42 -07:00
mofeiZ 1ee1afd2e0 [ez] Rewrite optional chaining and nullish coalescing syntax (#30982)
Rewrite `containerInfo?.ownerDocument?.defaultView ?? window` to instead
use a ternary.

This changes the compilation output (see [bundle changes from
#30951](https://github.com/facebook/react/commit/d65fb06955e9f32e6a40d1c7177d77893dff95b9)).
```js
// compilation of containerInfo?.ownerDocument?.defaultView ?? window
var $jscomp$optchain$tmpm1756096108$1, $jscomp$nullish$tmp0;
containerInfo =
  null !=
  ($jscomp$nullish$tmp0 =
    null == containerInfo
      ? void 0
      : null ==
          ($jscomp$optchain$tmpm1756096108$1 = containerInfo.ownerDocument)
        ? void 0
        : $jscomp$optchain$tmpm1756096108$1.defaultView)
    ? $jscomp$nullish$tmp0
    : window;

// compilation of ternary expression
containerInfo =
  null != containerInfo &&
  null != containerInfo.ownerDocument &&
  null != containerInfo.ownerDocument.defaultView
    ? containerInfo.ownerDocument.defaultView
    : window;
```

This also reduces the number of no-op bundle syncs for Meta. Note that
Closure compiler's `jscomp$optchain$tmp<HASH>` identifiers change when
we rebuild (likely due to version number changes). See
[workflow](https://github.com/facebook/react/actions/runs/10891164281/job/30221518374)
for a PR that was synced despite making no changes to the runtime.

DiffTrain build for [09d8283599](https://github.com/facebook/react/commit/09d82835993b16cd5dc8350c03627f9573354a25)
2024-09-18 11:47:14 -07:00
hoxyq 918b30cd6b chore: remove settings manager from react-devtools-core (#30986)
Stacked on https://github.com/facebook/react/pull/30636. See [this
commit](https://github.com/facebook/react/pull/30986/commits/20cec76c44f77e74b3a85225fecab5a431cd986f).

This has been only used for React Native and will be replaced by another
approach (initialization via `installHook` call) in the next PR.

DiffTrain build for [f2c57a31e9](https://github.com/facebook/react/commit/f2c57a31e9953b3889c56f68e129e67afca15d0e)
2024-09-18 10:38:31 -07:00
hoxyq 7ae2fa49c4 feat[react-devtools/extension]: use chrome.storage to persist settings across sessions (#30636)
Stacked on https://github.com/facebook/react/pull/30610 and whats under
it. See [last
commit](https://github.com/facebook/react/pull/30636/commits/248ddba18608e1bb5ef14c823085a7ff9d7a54a3).

Now, we are using
[`chrome.storage`](https://developer.chrome.com/docs/extensions/reference/api/storage)
to persist settings for the browser extension across different sessions.
Once settings are updated from the UI, the `Store` will emit
`settingsUpdated` event, and we are going to persist them via
`chrome.storage.local.set` in `main/index.js`.

When hook is being injected, we are going to pass a `Promise`, which is
going to be resolved after the settings are read from the storage via
`chrome.storage.local.get` in `hookSettingsInjector.js`.

DiffTrain build for [f37c7bc653](https://github.com/facebook/react/commit/f37c7bc6539b4da38f7080b5486eb00bdb2c3237)
2024-09-18 10:36:58 -07:00
hoxyq 7d2f2b9e0d refactor[react-devtools]: propagate settings from global hook object to frontend (#30610)
Stacked on https://github.com/facebook/react/pull/30597 and whats under
it. See [this
commit](https://github.com/facebook/react/pull/30610/commits/59b4efa72377bf62f5ec8c0e32e56902cf73fbd7).

With this change, the initial values for console patching settings are
propagated from hook (which is the source of truth now, because of
https://github.com/facebook/react/pull/30596) to the UI. Instead of
reading from `localStorage` the frontend is now requesting it from the
hook. This happens when settings modal is rendered, and wrapped in a
transition. Also, this is happening even if settings modal is not opened
yet, so we have enough time to fetch this data without displaying loader
or similar UI.

DiffTrain build for [e33acfd67f](https://github.com/facebook/react/commit/e33acfd67f0003272a9aec7a0725d19a429f2460)
2024-09-18 10:28:33 -07:00
hoxyq acd2b4fe5d chore[react-devtools]: extract some utils into separate modules to unify implementations (#30597)
Stacked on https://github.com/facebook/react/pull/30596. See [this
commit](https://github.com/facebook/react/pull/30597/commits/4ba5e784bbfdcd69021e2d84c75ffe26fcb698f4).

Moving `formatWithStyles` and `formatConsoleArguments` to its own
modules, so that we can finally have a single implementation for these
and stop inlining them in RDT global hook object.

DiffTrain build for [fce4606657](https://github.com/facebook/react/commit/fce46066571e7bf3ab6ce5bfe5fd3a615e098421)
2024-09-18 10:27:43 -07:00
hoxyq 8bc2b9c3f1 refactor[react-devtools]: remove browserTheme from ConsolePatchSettings (#30566)
Stacked on https://github.com/facebook/react/pull/30564.

We are no longer using browser theme in our console patching, this was
removed in unification of console patching for strict mode, we started
using ansi escape symbols and forking based on browser theme is no
longer required - https://github.com/facebook/react/pull/29869

The real browser theme initialization for frontend is happening at the
other place and is not affected:

https://github.com/facebook/react/blob/40be968257a7a10a267210670103f20dd0429ef3/packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js#L117-L120

DiffTrain build for [b521ef8a2a](https://github.com/facebook/react/commit/b521ef8a2aaff61154e59f6d0d3791ee4dbe6395)
2024-09-18 10:09:56 -07:00
hoxyq 6f757075f0 feat[react-devtools]: add settings to global hook object (#30564)
Right now we are patching console 2 times: when hook is installed
(before page is loaded) and when backend is connected. Because of this,
even if user had `appendComponentStack` setting enabled, all emitted
error and warning logs are not going to have component stacks appended.
They also won't have component stacks appended retroactively when user
opens browser DevTools (this is when frontend is initialized and
connects to backend).

This behavior adds potential race conditions with LogBox in React
Native, and also unpredictable to the user, because in order to get
component stacks logged you have to open browser DevTools, but by the
time you do it, error or warning log was already emitted.

To solve this, we are going to only patch console in the hook object,
because it is guaranteed to load even before React. Settings are going
to be synchronized with the hook via Bridge, and React DevTools Backend
Host (React Native or browser extension shell) will be responsible for
persisting these settings across the session, this is going to be
implemented in a separate PR.

DiffTrain build for [5e83d9ab3b](https://github.com/facebook/react/commit/5e83d9ab3b3f88853591dff43cd70ee4e5c90c5d)
2024-09-18 09:44:08 -07:00
jackpope c0925f3317 [compiler] Add JSX inlining optimization (#30867)
This adds an `InlineJsxTransform` optimization pass, toggled by the
`enableInlineJsxTransform` flag. When enabled, JSX will be transformed
into React Element object literals, preventing runtime overhead during
element creation.

TODO:
- [ ] Add conditionals to make transform PROD-only
- [ ] Make the React element symbol configurable so this works with
runtimes that support `react.element` or `react.transitional.element`
- [ ] Look into additional optimization to pass props spread through
directly if none of the properties are mutated

DiffTrain build for [5dcb009760](https://github.com/facebook/react/commit/5dcb009760160c085496e943f76090d98528f971)
2024-09-18 08:58:45 -07:00
sebmarkbage a5e6d678ba [Fiber] Color Performance Track Entries by Self Time (#30984)
Stacked on #30983.

This colors each component entry by its self time from light to dark
depending on how long it took. If it took longer than a cut off we color
it red (the error color).

<img width="435" alt="Screenshot 2024-09-16 at 11 48 15 PM"
src="https://github.com/user-attachments/assets/5d0bda83-6205-40e9-bec1-b81db2d48b2d">

DiffTrain build for [8dfbd16fce](https://github.com/facebook/react/commit/8dfbd16fce9077ab4e5fe85a7b86fa7c97a5ae04)
2024-09-17 13:43:35 -07:00
sebmarkbage 7b7ffbd4b5 [Fiber] Log Component Effects to Performance Track (#30983)
Stacked on #30981. Same as #30967 but for effects.

This logs a tree of components using `performance.measure()`.

In addition to the previous render phase this logs one tree for each
commit phase:

- Mutation Phase
- Layout Effect
- Passive Unmounts
- Passive Mounts

I currently skip the Before Mutation phase since the snapshots are so
unusual it's not worth creating trees for those.

The mechanism is that I reuse the timings we track for
`enableProfilerCommitHooks`. I track first and last effect timestamp
within each component subtree. Then on the way up do we log the entry.
This means that we don't include overhead to find our way down to a
component and that we don't need to add any additional overhead by
reading timestamps.

To ensure that the entries get ordered correctly we need to ensure that
the start time of each parent is slightly before the inner one.

DiffTrain build for [e1c20902c3](https://github.com/facebook/react/commit/e1c20902c39d1dfe2649185622f2f21b526e2be2)
2024-09-17 13:22:20 -07:00
sebmarkbage 2acc36c953 Don't read currentTransition back from internals (#30991)
This code is weird. It reads back the transition that it just set from
the shared internals. It's almost like it expects it to be a getter or
something.

This avoids that and makes it consistent with what ReactFiberHooks
already does.

DiffTrain build for [15da917451](https://github.com/facebook/react/commit/15da9174518f18f82869767ebe2a21be2fc8bd90)
2024-09-17 12:32:15 -07:00
sebmarkbage e70db3db9b [Fiber] Optimize enableProfilerCommitHooks by Collecting Elapsed Effect Duration in Module Scope (#30981)
Stacked on #30979.

The problem with the previous approach is that it recursively walked the
tree up to propagate the resulting time from recording a layout effect.

Instead, we keep a running count of the effect duration on the module
scope. Then we reset it when entering a nested Profiler and then we add
its elapsed count when we exit the Profiler.

This also fixes a bug where we weren't previously including unmount
times for some detached trees since they couldn't bubble up to find the
profiler.

DiffTrain build for [4549be0f84](https://github.com/facebook/react/commit/4549be0f846e7df5a4eaabf06369d93bd120271e)
2024-09-17 12:19:38 -07:00
mvitousek 905f7f3c7b [compiler][playground] create playground API in pipeline, and allow spaces in pass names
Summary:
1. Minor refactor to provide a stable API for calling the compiler from the playground
2. Allows spaces in pass names without breaking the appearance of the playground by replacing spaces with &nbsp; in pass tabs

ghstack-source-id: 12a43ad86c
Pull Request resolved: https://github.com/facebook/react/pull/30988

DiffTrain build for [7b56a54298](https://github.com/facebook/react/commit/7b56a542987890f618eeda4e4906fbf1f1df2213)
2024-09-17 11:13:16 -07:00
mofeiZ 9901f5a098 [compiler][eslint] Report bailout diagnostics with correct column # (#30977)
Compiler bailout diagnostics should now highlight only the first line of
the source location span.

(Resubmission of #30423 which was reverted due to invalid column
number.)

DiffTrain build for [a99d8e8d97](https://github.com/facebook/react/commit/a99d8e8d97055127a8ad7b01835d2660154689ed)
2024-09-16 13:03:43 -07:00
sebmarkbage 5776f4e27e Remove execution context check from shouldProfile (#30971)
I don't know why this is here since all these callsites are within the
CommitWork/CommitEffects helpers.

This should help with inlining.

DiffTrain build for [8152e5cd27](https://github.com/facebook/react/commit/8152e5cd27721e792f395c0b62c8a7769a54777a)
2024-09-16 12:07:15 -07:00
mvitousek f5d6218384 [compiler] Implement support for hoisted and recursive functions
Summary:
Introduces a new binding kind for functions that allows them to be hoisted. Also has the result of causing all nested function declarations to be outputted as function declarations, not as let bindings.

ghstack-source-id: fa40d4909f
Pull Request resolved: https://github.com/facebook/react/pull/30922

DiffTrain build for [d7167c3505](https://github.com/facebook/react/commit/d7167c35059bc6a0ad84eb34e65b3b66328d5dd8)
2024-09-16 11:20:30 -07:00
mvitousek 2f4fba4d70 [compiler] Allow all hooks to take callbacks which access refs, but ban hooks from taking direct ref value arguments
Summary:
This brings the behavior of ref mutation within hook callbacks into alignment with the behavior of global mutations--that is, we allow all hooks to take callbacks that may mutate a ref. This is potentially unsafe if the hook eagerly calls its callback, but the alternative is excessively limiting (and inconsistent with other enforcement).

This also bans *directly* passing a ref.current value to a hook, which was previously allowed.

ghstack-source-id: e66ce7123e
Pull Request resolved: https://github.com/facebook/react/pull/30917

DiffTrain build for [e78c9362c0](https://github.com/facebook/react/commit/e78c9362c014dccaed5ff193106e44d7d072dc32)
2024-09-16 11:04:44 -07:00
javache 6ba137bf82 [react-native] Fix misleading crash when view config is not found (#30970)
## Summary

When a view config can not be found, it currently errors with
`TypeError: Cannot read property 'bubblingEventTypes' of null`. Instead
invariant at the correct location and prevent further processing of the
null viewConfig to improve the error logged.

## How did you test this change?

Build and run RN playground app referencing an invalid native view
through `requireNativeComponent`.

DiffTrain build for [26855e4680](https://github.com/facebook/react/commit/26855e4680dedb21f2c73a069ed691822a242db1)
2024-09-16 09:58:01 -07:00
hoxyq a8693bec36 fix: add Error prefix to Error objects names (#30969)
This fixes printing Error objects in Chrome DevTools.

I've observed that Chrome DevTools is not source mapping and linkifying
URLs, when was running this on larger apps. Chrome DevTools talks to V8
via Chrome DevTools protocol, every object has a corresponding
[`RemoteObject`](https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-RemoteObject).

When Chrome DevTools sees that Error object is printed in the console,
it will try to prettify it. `description` field of the corresponding
`RemoteObject` for the `Error` JavaScript object is a combination of
`Error` `name`, `message`, `stack` fields. This is not just a raw
`stack` field, so our prefix for this field just doesn't work. [V8 is
actually filtering out first line of the `stack` field, it only keeps
the stack frames as a string, and then this gets prefixed by `name` and
`message` fields, if they are
available](https://source.chromium.org/chromium/chromium/src/+/main:v8/src/inspector/value-mirror.cc;l=252-311;drc=bdc48d1b1312cc40c00282efb1c9c5f41dcdca9a?fbclid=IwZXh0bgNhZW0CMTEAAR1tMm5YC4jqowObad1qXFT98X4RO76CMkCGNSxZ8rVsg6k2RrdvkVFL0i4_aem_e2fRrqotKdkYIeWlJnk0RA).
As an illustration, this:
```
const fakeError = new Error('');
fakeError.name = 'Stack';
fakeError.stack = 'Error Stack:' + stack;
```

will be formatted by `V8` as this `RemoteObject`:
```
{
  ...
  description: 'Stack: ...',
  ...
}
```

Notice that there is no `Error` prefix, that was previously added.
Because of this, [Chrome DevTools won't even try to symbolicate the
stack](https://github.com/ChromeDevTools/devtools-frontend/blob/ee4729d2ccdf5c6715ee40e6697f5464829e3f9a/front_end/panels/console/ErrorStackParser.ts#L33-L35),
because it doesn't have such prefix.

DiffTrain build for [9f4e4611ea](https://github.com/facebook/react/commit/9f4e4611ead28d34f7f598c9bd12424cf68f5781)
2024-09-16 09:51:18 -07:00
sebmarkbage 07973576bd [Fiber] Log Component Renders to Custom Performance Track (#30967)
Stacked on #30960 and #30966. Behind the enableComponentPerformanceTrack
flag.

This is the first step of performance logging. This logs the start and
end time of a component render in the passive effect phase. We use the
data we're already tracking on components when the Profiler component or
DevTools is active in the Profiling or Dev builds. By backdating this
after committing we avoid adding more overhead in the hot path. By only
logging things that actually committed, we avoid the costly unwinding of
an interrupted render which was hard to maintain in earlier versions.

We already have the start time but we don't have the end time. That's
because `actualStartTime + actualDuration` isn't enough since
`actualDuration` counts the actual CPU time excluding yields and
suspending in the render.

Instead, we infer the end time to be the start time of the next sibling
or the complete time of the whole root if there are no more siblings. We
need to pass this down the passive effect tree. This will mean that any
overhead and yields are attributed to this component's span. In a follow
up, we'll need to start logging these yields to make it clear that this
is not part of the component's self-time.

In follow ups, I'll do the same for commit phases. We'll also need to
log more information about the phases in the top track. We'll also need
to filter out more components from the trees that we don't need to
highlight like the internal Offscreen components. It also needs polish
on colors etc.

Currently, I place the components into separate tracks depending on
which lane currently committed. That way you can see what was blocking
Transitions or Suspense etc. One problem that I've hit with the new
performance.measure extensions is that these tracks show up in the order
they're used which is not the order of priority that we use. Even when
you add fake markers they have to actually be within the performance run
since otherwise the calls are noops so it's not enough to do that once.

However, I think this visualization is actually not good because these
trees end up so large that you can't see any other lanes once you expand
one. Therefore, I think in a follow up I'll actually instead switch to a
model where Components is a single track regardless of lane since we
don't currently have overlap anyway. Then the description about what is
actually rendering can be separate lanes.

<img width="1512" alt="Screenshot 2024-09-15 at 10 55 55 PM"
src="https://github.com/user-attachments/assets/5ca3fa74-97ce-40c7-97f7-80c1dd7d6470">

<img width="1512" alt="Screenshot 2024-09-15 at 10 56 27 PM"
src="https://github.com/user-attachments/assets/557ad65b-4190-465f-843c-0bc6cbb9326d">

DiffTrain build for [f2df5694f2](https://github.com/facebook/react/commit/f2df5694f2be141954f22618fd3ad035203241a3)
2024-09-16 08:53:04 -07:00
sebmarkbage be5e283e53 Add enableComponentPerformanceTrack Flag (#30960)
This flag will be used to gate a new timeline profiler that's integrate
with the Performance Tab and the new performance.measure extensions in
Chrome.

It replaces the existing DevTools feature so this disables
enableSchedulingProfiler when it is enabled since they can interplay in
weird ways potentially.

This means that experimental React now disable scheduling profiler and
enables this new approach.

DiffTrain build for [0eab377a96](https://github.com/facebook/react/commit/0eab377a96099f0121009c8968c49d13d4e00bd1)
2024-09-16 08:17:42 -07:00
hoxyq 2875993c07 fix[rdt/fiber/renderer.js]: getCurrentFiber can be injected as null (#30968)
In production artifacts for `18.x.x` `getCurrentFiber` can actually be
injected as `null`. Updated `getComponentStack` and `onErrorOrWarning`
implementations to support this.

![Screenshot 2024-09-16 at 10 52
00](https://github.com/user-attachments/assets/a0c773aa-ebbf-4fd5-95c4-cac3cc0c203f)

DiffTrain build for [8cf64620c7](https://github.com/facebook/react/commit/8cf64620c7dd4ec7e72aa16ee2d5f15eb3420b92)
2024-09-16 06:54:58 -07:00
gnoff a53353a14d [Flight] Start initial work immediately (#30961)
In a past update we made render and prerender have different work
scheduling behavior because these methods are meant to be used in
differeent environments with different performance tradeoffs in mind.
For instance to prioritize streaming we want to allow as much IO to
complete before triggering a round of work because we want to flush as
few intermediate UI states. With Prerendering there will never be any
intermediate UI states so we can more aggressively render tasks as they
complete.

One thing we've found is that even during render we should ideally kick
off work immediately. This update normalizes the intitial work for
render and prerender to start in a microtask. Choosing microtask over
sync is somewhat arbitrary but there really isn't a reason to make them
different between render/prerender so for now we'll unify them and keep
it as a microtask for now.

This change also updates pinging behavior. If the request is still in
the initial task that spawned it then pings will schedule on the
microtask queue. This allows immediately available async APIs to resolve
right away. The concern with doing this for normal pings is that it
might crowd out IO events but since this is the initial task there would
be IO to already be scheduled.

DiffTrain build for [fc5ef50da8](https://github.com/facebook/react/commit/fc5ef50da8e975a569622d477f1fed54cb8b193d)
2024-09-14 09:32:59 -07:00
gnoff 36ded714ec Fix nodeName to UPPERCASE in insertStylesheetIntoRoot (#28255)
## Summary

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

<img width="518" alt="image"
src="https://github.com/facebook/react/assets/18693190/6d12df76-7dae-403b-b486-4940992abe8d">

The condition `node.nodeName === 'link'` is always `false`, because
`node.nodeName` is Uppercase in specification. And the condition
`node.nodeName === 'LINK'` is unnecessary, because Fizz hoists tags when
it's `media` attribute is `"not all"`, whether it is a `link` or a
`style` (line 36):

https://github.com/facebook/react/blob/18cbcbf783377c5a22277a63ae41af54504502e0/packages/react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetExternalRuntime.js#L30-L44

https://github.com/facebook/react/blob/18cbcbf783377c5a22277a63ae41af54504502e0/packages/react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetInlineSource.js#L30-L44

DiffTrain build for [b75cc078c5](https://github.com/facebook/react/commit/b75cc078c5fda0d57135523a7a2f4e8d1536472f)
2024-09-14 08:25:42 -07:00
sebmarkbage a2485b7960 [Fiber] Profiler - Use two separate functions instead of branch by flag (#30957)
Nit: I don't trust flags in hot code. While it can take somewhat longer
to compile two functions and JIT them. After that they don't need to
check branches. Also makes it clearer the purpose.

DiffTrain build for [3d95c43b89](https://github.com/facebook/react/commit/3d95c43b8967d4dda1ec9a22f0d9ea4999fee8b8)
2024-09-13 18:58:53 -07:00
gnoff c8d8c3ea5e [Flight] properly track pendingChunks when changing environment names (#30958)
When the environment name changes for a chunk we issue a new debug chunk
which updates the environment name. This chunk was not beign included in
the pendingChunks count so the count was off when flushing

DiffTrain build for [6774caa379](https://github.com/facebook/react/commit/6774caa37973e3e26d60f100971e5e785fd12235)
2024-09-13 16:02:52 -07:00
sebmarkbage 0252a0b7cb [Flight] Respect async flag in client manifest (#30959)
In #26624, the ability to mark a client reference module as `async` in
the React client manifest was removed because it was not utilized by
Webpack, neither in `ReactFlightWebpackPlugin` nor in Next.js. However,
some bundlers and frameworks are sophisticated enough to properly handle
and identify async ESM modules (e.g., client component modules with
top-level `await`), most notably Turbopack in Next.js. Therefore, we
need to consider the `async` flag in the client manifest when resolving
the client reference metadata on the server. The SSR manifest cannot
override this flag, meaning that if a module is async, it must remain
async in all client environments.

x-ref: https://github.com/vercel/next.js/pull/70022

DiffTrain build for [5deb78223a](https://github.com/facebook/react/commit/5deb78223a269a6cb1706da8ec6aad8c007cab03)
2024-09-13 13:40:38 -07:00
josephsavona d65fb06955 fix: restore selection should consider the window of the container (#30951)
## Summary

Fixes #30864

Before this PR the active elemen was always taken from the global
`window`. This is incorrect if the renderer is in one window rendering
into a container element in another window. The changes in this PR adds
another code branch to use a `defaultView` of the container element if
it exists so that `restoreSelection` after a commit will actually
restore to the correct window.

## How did you test this change?

I patched these changes to the repro repo in the linked issue #39864
https://github.com/ling1726/react-child-window-focus-repro/blob/master/patches/react-dom%2B18.3.1.patch.

I followed the same repro steps in the linked issue and and could not
repro the reported problem. Attaching screen recordings below:

Before
![focus
repro](https://github.com/user-attachments/assets/81c4b4f9-08b5-4356-8251-49b909771f3f)

After

![after](https://github.com/user-attachments/assets/84883032-5558-4650-9b9a-bd4d5fd9cb13)

DiffTrain build for [d9c4920e8b](https://github.com/facebook/react/commit/d9c4920e8b3fff3d3da24d14adf7ac884aee55b2)
2024-09-13 13:36:35 -07:00
rickhanlonii 9d3ed27e04 Call cleanup of insertion effects when hidden (#30954)
Insertion effects do not unmount when a subtree is removed while
offscreen.

Current behavior for an insertion effect is if the component goes

- *visible -> removed:* calls insertion effect cleanup
- *visible -> offscreen -> removed:* insertion effect cleanup is never
called

This makes it so we always call insertion effect cleanup when removing
the component.

Likely also fixes https://github.com/facebook/react/issues/26670

---------

Co-authored-by: Rick Hanlon <rickhanlonii@fb.com>

DiffTrain build for [d3d4d3a46b](https://github.com/facebook/react/commit/d3d4d3a46b014ab0f6edc443c19fcdba09105f20)
2024-09-13 13:25:39 -07:00
sebmarkbage 037b2e3088 [Fiber] Set profiler values to doubles (#30942)
At some point this trick was added to initialize the value first to NaN
and then replace them with zeros and negative ones.

This is to address the issue noted in
https://github.com/facebook/react/issues/14365 where these hidden
classes can be initialized to SMIs at first and then deopt when we
realize they're actually doubles.

However, this fix has been long broken and has deopted the profiling
build for years because closure compiler optimizes out the first write.

I'm not sure because I haven't A/B-tested this in the JIT yet but I
think we can use negative zero and -1.1 as the initial values instead
since they're not simple integers. Negative zero `===` zero (but not
Object.is) so is the same as far as our code is concerned. The negative
value is just `< 0` comparisons.

DiffTrain build for [94e4acaa14](https://github.com/facebook/react/commit/94e4acaa1477e65cac02ba86058cde0afe4c8f1f)
2024-09-13 09:33:56 -07:00
sebmarkbage fadd1eee06 [Fizz] Add resumeAndPrerender to Static Rendering (#30950)
This is only in the same experimental exports as `resume`. Useful with
Postpone/Halt.

We already have `prerender()` to create a partial tree with postponed
state. We also have `resume()` to dynamically resume such a tree.

This lets you do a new prerender by resuming an already existing
postponed state. Basically creating a chain of preludes. The next
prelude would include the scripts to patch up the document.

This mostly just works since both prerender and resume are already
implemented using the same code so we just enable both at the root. I'm
sure we'll find some edge cases since this wasn't considered when it was
first written but so far I've only found an unrelated existing bug with
`keyPath` fixed here.

DiffTrain build for [473522093d](https://github.com/facebook/react/commit/473522093d3dd95582729d01cd5c0d15dcc9cd3b)
2024-09-12 07:58:29 -07:00
acdlite ed8cad438e Start prerendering Suspense retries immediately (#30934)
When a component suspends and is replaced by a fallback, we should start
prerendering the fallback immediately, even before any new data is
received. During the retry, we can enter prerender mode directly if
we're sure that no new data was received since we last attempted to
render the boundary.

To do this, when completing the fallback, we leave behind a pending
retry lane on the Suspense boundary. Previously we only did this once a
promise resolved, but by assigning a lane during the complete phase, we
will know that there's speculative work to be done.

Then, upon committing the fallback, we mark the retry lane as suspended
— but only if nothing was pinged or updated in the meantime. That allows
us to immediately enter prerender mode (i.e. render without skipping any
siblings) when performing the retry.

DiffTrain build for [d6cb4e7713](https://github.com/facebook/react/commit/d6cb4e771341ff82489c00f4907990cb8a75696b)
2024-09-11 08:49:16 -07:00
sebmarkbage c63274417d [Fizz] Use RequestInstance constructor for resuming (#30947)
We added enough fields to need a constructor instead of inline object in
V8.

We didn't update the resumeRequest path though so it wasn't using the
constructor and had a different hidden class.

DiffTrain build for [1bb056363c](https://github.com/facebook/react/commit/1bb056363c02fa9d188cc1122595d1587aa59d86)
2024-09-11 08:43:01 -07:00
sebmarkbage b8a98add1f [Fiber] Don't call performance.now() twice in a row (#30936)
DiffTrain build for [a5a7f1063e](https://github.com/facebook/react/commit/a5a7f1063e6f190c64c779b2aa54d28fb7b92cfb)
2024-09-10 13:54:18 -07:00
acdlite bf9385a46c Prerender during same pass if blocked anyway (#30879)
If something suspends in the shell — i.e. we won't replace the suspended
content with a fallback — we might as well prerender the siblings during
the current render pass, instead of spawning a separate prerender pass.

This is implemented by setting the "is prerendering" flag to true
whenever we suspend in the shell. But only if we haven't already skipped
over some siblings, because if so, then we need to schedule a separate
prerender pass regardless.

DiffTrain build for [66cf2cfc8a](https://github.com/facebook/react/commit/66cf2cfc8a8c4b09d2b783fd7302ae6b24150935)
2024-09-10 10:30:55 -07:00
sebmarkbage 4d30e52d65 [DevTools] Use Unicode Atom Symbol instead of Atom Emoji (#30832)
This reverts #19603.

Before:
<img width="724" alt="Screenshot 2024-08-28 at 12 07 29 AM"
src="https://github.com/user-attachments/assets/0613088f-c013-4f1c-92c3-fbdae8c1f109">

After:
<img width="771" alt="Screenshot 2024-08-28 at 12 08 13 AM"
src="https://github.com/user-attachments/assets/eef21bee-d11f-4f0a-9147-053a163f720f">

Consensus seems to be that while the purple on is a bit clearer and
easier to read. The purple is not on brand so it doesn't look like
React. It looks ugly. It's distracting (too eye catching). Taking away
attention from other tabs in an unfair way.

It also gets worse with more tabs added. We plan on both adding another
tab and panes inside other tabs (elements/sources) soon. Each needs to
be marked somehow as part of React but spelling it out is too long.
Putting inside a second tab means two clicks and takes away real-estate
from our extension and doesn't solve the problem with extension panes in
other tabs. We also plan on adding multiple different tracks to the
Performance tab which also needs a name other than just React and
spelling out React as a prefix is too long. The Emoji is too
distracting. So it seems best to uniformly apply the symbol - albeit it
might just look like a dot to many.

Dark mode looks close to on brand:

<img width="1089" alt="Screenshot 2024-08-28 at 12 32 50 AM"
src="https://github.com/user-attachments/assets/7175a540-4241-4c26-9e4d-4d367873af57">

DiffTrain build for [d160aa0fbb](https://github.com/facebook/react/commit/d160aa0fbb1bd2d00ea8c771c551c9cb5b47f1e9)
2024-09-09 21:16:50 -07:00
josephsavona eb67bf1b96 Fix useMemoCache with setState in render
Fixes the bug that @alexmckenley and @mofeiZ found where setState-in-render can reset useMemoCache and cause an infinite loop. The bug was that renderWithHooksAgain() was not resetting hook state when rerendering (so useMemo values were preserved) but was resetting the updateQueue. This meant that the entire memo cache was cleared on a setState-in-render.

The fix here is to call a new helper function to clear the update queue. It nulls out other properties, but for memoCache it just sets the index back to zero.

ghstack-source-id: fc0947ce21
Pull Request resolved: https://github.com/facebook/react/pull/30889

DiffTrain build for [727b361528](https://github.com/facebook/react/commit/727b3615287074ddaa28069bfbd2dfee8cf73575)
2024-09-06 14:40:38 -07:00
sebmarkbage 716cd41764 [Fiber] Move runWithFiberInDEV from CommitWork to CommitEffects (#30882)
Stacked on #30881.

Move `runWithFiberInDEV` from the recursive part of the commit phase and
instead wrap each call into user space. These should really map 1:1 with
where we're using `try/catch` since that's where we're calling into user
space.

The goal of this is to avoid the extra stack frames added by
`enableOwnerStacks` in the recursive parts to avoid stack overflow. This
way we only have a couple of extra at the end of the stack instead of a
couple of extra at every depth of the tree.

DiffTrain build for [a03254bc60](https://github.com/facebook/react/commit/a03254bc60b06c535c37e43c53b1fd40757b2ef4)
2024-09-05 18:04:06 -07:00