Commit Graph

2036 Commits

Author SHA1 Message Date
Jack Pope d8c90fa48d 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.
2024-10-01 11:00:57 -04:00
Ricky 76aee6f39d Revert "Make prerendering always non-blocking" (#31080)
Reverts facebook/react#31056
2024-09-26 16:48:57 -04:00
Sebastian "Sebbie" Silbermann 778e1ed2e5 [Fiber] Fix missing render times when we cancel a pending commit (#31065) 2024-09-26 00:20:03 +02:00
Andrew Clark 0f1856c49f 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.
2024-09-25 16:31:44 -04:00
Andrew Clark 3c7667a694 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.)
2024-09-25 14:33:11 -04:00
Jack Pope f9ebd85a19 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.
2024-09-25 11:50:41 -04:00
Sebastian Markbåge 4e9540e3c2 [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.
2024-09-23 14:09:48 -04:00
Sebastian Markbåge d4688dfaaf [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.
2024-09-20 14:27:12 -04:00
Sebastian Markbåge 8dfbd16fce [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">
2024-09-17 16:36:10 -04:00
Sebastian Markbåge e1c20902c3 [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.
2024-09-17 16:14:57 -04:00
Sebastian Markbåge 4549be0f84 [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.
2024-09-17 15:12:16 -04:00
Sebastian Markbåge 8152e5cd27 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.
2024-09-16 15:00:17 -04:00
Sebastian Markbåge f2df5694f2 [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">
2024-09-16 11:45:50 -04:00
Sebastian Markbåge ee1a403a30 [Fiber] Move Profiler onPostCommit processing of passive effect durations to plain passive effect (#30966)
We used to queue a separate third passive phase to invoke onPostCommit
but this is unnecessary. We can just treat it as a plain passive effect.
This means it is interleaved with other passive effects but we only need
to know the duration of the things below us which is already done at
this point.

I also extracted the user space call to onPostCommit into
ReactCommitEffects. Same as onCommit. It's now covered by
runWithFiberInDEV and catches.
2024-09-16 11:10:05 -04:00
Sebastian Markbåge 3d95c43b89 [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.
2024-09-13 21:51:52 -04:00
Jan Kassens d3d4d3a46b 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>
2024-09-13 16:18:14 -04:00
Sebastian Markbåge 94e4acaa14 [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.
2024-09-13 12:27:00 -04:00
Andrew Clark d6cb4e7713 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.
2024-09-11 11:41:54 -04:00
Sebastian Markbåge a5a7f1063e [Fiber] Don't call performance.now() twice in a row (#30936) 2024-09-10 16:46:35 -04:00
Andrew Clark 66cf2cfc8a 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.
2024-09-10 13:23:32 -04:00
Sebastian Markbåge d160aa0fbb [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">
2024-09-10 00:09:42 -04:00
Joe Savona 727b361528 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
2024-09-06 14:32:18 -07:00
Sebastian Markbåge a03254bc60 [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.
2024-09-05 20:54:39 -04:00
Sebastian Markbåge fe03c56d1e [Fiber] Extract Functions that Call User Space and Host Configs in Commit to Separate Modules (#30881)
This is mostly just moves and same code extracted into utility
functions.

This is to help clarify what needs to be wrapped in try/catch and
runWithFiberInDEV. I'll do the runWithFiberInDEV changes in a follow up.

This leaves ReactCommitWork mostly to do matching on the tag and the
recursive loops.
2024-09-05 20:53:27 -04:00
mofeiZ d72e477814 [compiler runtime] repro: infinite render with useMemoCache + render phase updates (#30849)
Repro for an infinite render bug we found when testing internally. See
equivalent codesandbox repro
[here](https://codesandbox.io/p/sandbox/epic-euclid-mr7lm3).

When render phase updates cause a re-render, useMemoCache arrays for the
fiber are
[cleared](https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberHooks.js#L819)
and [recreated on every
retry](https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberHooks.js#L1223)
while hook state is preserved.

This pattern (queuing re-renders on the current fiber during render) is
perfectly valid. I believe this is a bug as React compiler currently
replaces `useMemo`s with `useMemoCache` calls and inlined instructions,
taking care to preserve existing memoization dependencies. This should
be the identity transform, but runtime implementation differences mean
that uncompiled code behaves as expected (no infinite render) while
compiled code fails to render.
2024-09-05 13:30:34 -04:00
Andrew Clark e10e868182 Schedule prerender after something suspends (#30800)
Adds the concept of a "prerender". These special renders are spawned
whenever something suspends (and we're not already prerendering).

The purpose is to move speculative rendering work into a separate phase
that does not block the UI from updating. For example, during a
transition, if something suspends, we should not speculatively prerender
siblings that will be replaced by a fallback in the UI until *after* the
fallback has been shown to the user.
2024-09-04 13:55:29 -04:00
Andrew Clark 8b4c54c00f Temporarily disable suspending during work loop (#30762)
### Based on

- #30761 
- #30759 

---

`use` has an optimization where in some cases it can suspend the work
loop during the render phase until the data has resolved, rather than
unwind the stack and lose context. However, the current implementation
is not compatible with sibling prerendering. So I've temporarily
disabled it until the sibling prerendering has been refactored. We will
add it back in a later step.
2024-09-04 12:38:36 -04:00
Sebastian Markbåge 8d68da3f73 [Fiber] Stash ThenableState on the Dependencies Object for Use By DevTools (#30866)
This lets us track what a Component might suspend on from DevTools. We
could already collect this by replaying a component's Hooks but that
would be expensive to collect from a whole tree.

The thenables themselves might contain useful information but mainly
we'd want access to the `_debugInfo` on the thenables which might
contain additional information from the server.


https://github.com/facebook/react/blob/19bd26beb689e554fceb0b929dc5199be8cba594/packages/shared/ReactTypes.js#L114

In a follow up we should really do something similar in Flight to
transfer `use()` on the debugInfo of that Server Component.
2024-09-03 16:04:24 -04:00
Benoit Girard 246d7bfeb0 Enable suspenseCallback on React Native (#29210)
## Summary

suspenseCallback feature has proved to be useful for FB Web. Let's look
at enabling the feature for the React Native build.


## How did you test this change?

Will sync the react changes with a React Native build and will verify
that performance logging is correctly notified of suspense promises
during the suspense callback.
2024-08-26 22:06:02 -04:00
Andrew Clark ee7f6757c4 Fix: Synchronous popstate transitions (#30759)
This is a refactor of the fix in #27505.

When a transition update is scheduled by a popstate event, (i.e. a back/
forward navigation) we attempt to render it synchronously even though
it's a transition, since it's likely the previous page's data is cached.

In #27505, I changed the implementation so that it only "upgrades" the
priority of the transition for a single attempt. If the attempt
suspends, say because the data is not cached after all, from then on it
should be treated as a normal transition.

But it turns out #27505 did not work as intended, because it relied on
marking the root with pending synchronous work (root.pendingLanes),
which was never cleared until the popstate update completed.

The test scenarios I wrote accidentally worked for a different reason
related to suspending the work loop, which I'm currently in the middle
of refactoring.
2024-08-23 12:30:08 -04:00
dan 7e8a06cf4c [Fresh] Always reset useMemoCache on Fast Refresh (#30700)
Stacked on https://github.com/facebook/react/pull/30662.

Alternative to https://github.com/facebook/react/pull/30663 and
https://github.com/facebook/react/pull/30677.

During a Fast Refresh, we always want to evict the memo cache, same as
we do with normal `useMemo`. The mechanism used by `useMemo` and other
Hooks is this module-level variable:


https://github.com/facebook/react/blob/fca5d655d78917400a2722287351c20938166669/packages/react-reconciler/src/ReactFiberHooks.js#L304-L307

which has DEV-only behavior as if the dependencies are always different:


https://github.com/facebook/react/blob/fca5d655d78917400a2722287351c20938166669/packages/react-reconciler/src/ReactFiberHooks.js#L451-L460

The `useMemoCache` Hook doesn't use a dependency array but conceptually
I think we want the same behavior.

## Test Plan

The test passes.

---------

Co-authored-by: Lauren Tan <poteto@users.noreply.github.com>
2024-08-15 01:02:29 +01:00
Sebastian Silbermann e0a0e65412 Move react-html to react-markup (#30688) 2024-08-14 19:22:44 +02:00
Jack Pope 0ad0fac1dc Fix unstable_useContextWithBailout dispatcher assignment (#30692)
One more copy pasta fix

Assignments are unique now
```
% cat packages/react-reconciler/src/ReactFiberHooks.js | grep .unstable_useContextWithBailout
function unstable_useContextWithBailout<T>(
  (ContextOnlyDispatcher: Dispatcher).unstable_useContextWithBailout =
  (HooksDispatcherOnMount: Dispatcher).unstable_useContextWithBailout =
    unstable_useContextWithBailout;
  (HooksDispatcherOnUpdate: Dispatcher).unstable_useContextWithBailout =
    unstable_useContextWithBailout;
  (HooksDispatcherOnRerender: Dispatcher).unstable_useContextWithBailout =
    unstable_useContextWithBailout;
    (HooksDispatcherOnMountInDEV: Dispatcher).unstable_useContextWithBailout =
        return unstable_useContextWithBailout(context, select);
    (HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher).unstable_useContextWithBailout =
        return unstable_useContextWithBailout(context, select);
    (HooksDispatcherOnUpdateInDEV: Dispatcher).unstable_useContextWithBailout =
        return unstable_useContextWithBailout(context, select);
    (HooksDispatcherOnRerenderInDEV: Dispatcher).unstable_useContextWithBailout =
        return unstable_useContextWithBailout(context, select);
    (InvalidNestedHooksDispatcherOnMountInDEV: Dispatcher).unstable_useContextWithBailout =
        return unstable_useContextWithBailout(context, select);
    (InvalidNestedHooksDispatcherOnUpdateInDEV: Dispatcher).unstable_useContextWithBailout =
        return unstable_useContextWithBailout(context, select);
    (InvalidNestedHooksDispatcherOnRerenderInDEV: Dispatcher).unstable_useContextWithBailout =
        return unstable_useContextWithBailout(context, select);
```
2024-08-14 11:04:42 -04:00
Jack Pope d48603a525 Fix unstable_useContextWithBailout incorrect dispatcher assignment (#30673)
Fixing a mistaken copy from another dispatcher property assignment
2024-08-13 11:31:44 -04:00
Jan Kassens 65903583d2 Remove flag enableUseDeferredValueInitialArg (#30595)
This is enabled everywhere for a while and I don't think we'd be backing
this out of 19. Seems like it's good to clean up to me.
2024-08-05 11:25:05 -04:00
Jan Kassens 5fb67fa25c Cloned flag to avoid extra clones in persistent renderer (#27647)
Persistent renderers used the `Update` effect flag to check if a subtree
needs to be cloned. In some cases, that causes extra renders, such as
when a layout effect is triggered which only has an effect on the JS
side, but doesn't update the host components.

It's been a bit tricky to find the right places where this needs to be
set and I'm not 100% sure I got all the cases even though the tests
passed.
2024-08-01 15:11:19 -04:00
Sebastian Silbermann 88ee14ffa5 [Devtools] Ensure initial read of useFormStatus returns NotPendingTransition (#28728) 2024-08-01 10:55:53 +02:00
dan 96f3093bec Remove RefreshRuntime.findAffectedHostInstances (#30538)
I originally added this with a plan to visualize which nodes got updated
after a Fast Refresh. I didn't end up implementing that part, and to my
knowledge, no actively used integration actually does that or use this
method.

- [Webpack plugin doesn't use
it](https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/f1c8b9a44198449093ca95f85af5df97925e1cfc/lib/runtime/RefreshUtils.js)
- [RN doesn't use
it](https://github.com/facebook/react-native/blob/23c5c42de01953ed7b8e8938c2d3a8fac82250a0/packages/react-native/Libraries/Core/setUpReactRefresh.js)
- [Global GitHub code
search](https://github.com/search?q=findAffectedHostInstances&type=code&p=1)
only shows copies of this code and the type definition based on it, but
not actual calls to it

We should be able to delete this without a problem.
2024-07-30 22:06:16 +01:00
Sebastian Markbåge 146df7c311 [Fiber] Make DevTools Config use Static Injection (#30522)
We use static dependency injection. We shouldn't use this dynamic
dependency injection we do for DevTools internals. There's also meta
programming like spreading and stuff that isn't needed.

This moves the config from `injectIntoDevTools` to the FiberConfig so it
can be statically resolved.

Closure Compiler has some trouble generating optimal code for this
anyway so ideally we'd refactor this further but at least this is better
and saves a few bytes and avoids some code paths (when minified).
2024-07-30 15:03:54 -04:00
Sebastian Markbåge bea5a2bc46 [Fiber/DevTools] Stop injecting findHostInstanceByFiber (#30519)
This is not used by DevTools since it has its own implementation of it.

This function is getting removed since `findDOMNode` is getting removed
so we shouldn't keep around extra bytes unnecessarily.

There is also `findHostInstancesForRefresh` which should really be
implemented on the `react-refresh` side. Not using an injection but
that's a heavier lift and only affects `__DEV__`.
2024-07-29 20:05:14 -04:00
Jack Pope 1350a85980 Add unstable context bailout for profiling (#30407)
**This API is not intended to ship. This is a temporary unstable hook
for internal performance profiling.**

This PR exposes `unstable_useContextWithBailout`, which takes a compare
function in addition to Context. The comparison function is run to
determine if Context propagation and render should bail out earlier.
`unstable_useContextWithBailout` returns the full Context value, same as
`useContext`.

We can profile this API against `useContext` to better measure the cost
of Context value updates and gather more data around propagation and
render performance.

The bailout logic and test cases are based on
https://github.com/facebook/react/pull/20646

Additionally, this implementation allows multiple values to be compared
in one hook by returning a tuple to avoid requiring additional Context
consumer hooks.
2024-07-26 14:38:24 -04:00
Sebastian Markbåge e8df0cf9f7 Switch to binding the console with badging instead of calling it directly (#30461)
This is a major nit but this avoids an extra stack frame when we're
replaying logs.

Normally the `printToConsole` frame doesn't show up because it'd be
ignore listed.

<img width="421" alt="Screenshot 2024-07-25 at 11 49 39 AM"
src="https://github.com/user-attachments/assets/81334c2f-e19e-476a-871e-c4db9dee294e">

When you expand to show ignore listed frames a ton of other frames show
up.

<img width="516" alt="Screenshot 2024-07-25 at 11 49 47 AM"
src="https://github.com/user-attachments/assets/2ab8bdfb-464c-408d-9176-ee2fabc114b6">

The annoying thing about this frame is that it's at the top of the stack
where as typically framework stuff ends up at the bottom and something
you can ignore. The user space stack comes first.

With this fix there's no longer any `printToConsole` frame.

<img width="590" alt="Screenshot 2024-07-25 at 12 09 09 PM"
src="https://github.com/user-attachments/assets/b8365d53-31f3-43df-abce-172d608d3c9c">

Am I wiling to eat the added complexity and slightly slower performance
for this nit? Definitely.
2024-07-25 12:32:16 -04:00
Jack Pope 14a4699ff1 Remove allowConcurrentByDefault flag (#30445)
Following https://github.com/facebook/react/pull/30436

Concurrent by default strategy has been unshipped. Here we clean up the
`allowConcurrentByDefault` path and related logic/tests.

For now, this keeps the `concurrentUpdatesByDefaultOverride` argument in
`createContainer` and `createHydrationContainer` and ignores the value
to prevent more breaking changes to `react-reconciler` in the RC stage.
2024-07-25 11:59:50 -04:00
Sebastian Markbåge 5b37af7daa Stop filtering owner stacks (#30438)
We still filter them before passing from server to client in Flight
Server but when presenting a native stack, we don't need to filter them.
That's left to ignore listing in the presentation.

The stacks are pretty clean regardless thanks to the bottom stack
frames.

We can also unify the owner stack formatters into one shared module
since Fizz/Flight/Fiber all do the same thing. DevTools currently does
the same thing but is forked so it can support multiple versions.
2024-07-24 13:01:07 -04:00
Jack Pope e902c45caf Remove forceConcurrentByDefaultForTesting flag (#30436)
Concurrent by default has been unshipped! Let's clean it up.

Here we remove `forceConcurrentByDefaultForTesting`, which allows us to
run tests against both concurrent strategies. In the next PR, we'll
remove the actual concurrent by default code path.
2024-07-24 10:17:33 -04:00
Sebastian Markbåge da4abf0047 [Fiber] Call life-cycles with a react-stack-bottom-frame stack frame (#30429)
Stacked on #30427.

Most hooks and such are called inside renders which already have these
on the stack but life-cycles that call out on them are useful to cut off
too.

Typically we don't create JSX in here so they wouldn't be part of owner
stacks anyway but they can be apart of plain stacks such as the ones
prefixes to console logs or printed by error dialogs.

This lets us cut off any React internals below. This should really be
possible using just ignore listing too ideally.

At this point we should maybe just build a Babel plugin that lets us
annotate a function to need to have this name.
2024-07-23 18:49:42 -04:00
Tom Sherman 9cc0f6e68d Log Fragment name when trying to render a lazy fragment (#30372) 2024-07-23 19:00:51 +02:00
Jan Kassens b7e7f1a3fa [BE] upgrade prettier to 3.3.3 (#30420)
Mostly just changes in ternary formatting.
2024-07-22 16:09:01 -04:00
Jan Kassens d7c4334ce9 Add _debugStack and _debugTask under enableObjectFiber flag (#30337) 2024-07-22 14:10:08 -04:00
Sebastian Markbåge 06763852de [Flight] Parse Stack on the Server and Transfer Structured Stack (#30410)
Stacked on #30401.

Previously we were transferring the original V8 stack trace string to
the client and then parsing it there. However, really the server is the
one that knows what format it is and it should be able to vary by server
environment.

We also don't use the raw string anymore (at least not in
enableOwnerStacks). We always create the native Error stacks.

The string also made it unclear which environment it is and it was
tempting to just use it as is.

Instead I parse it on the server and make it a structured stack in the
transfer format. It also makes it clear that it needs to be formatted in
the current environment before presented.
2024-07-22 11:18:55 -04:00