-
Notifications
You must be signed in to change notification settings - Fork 49.9k
Comparing changes
Open a pull request
base repository: facebook/react
base: 1324e1bb
head repository: facebook/react
compare: 58bdc0bb
- 13 commits
- 50 files changed
- 4 contributors
Commits on Oct 17, 2025
-
[compiler] More fbt compatibility (#34887)
In my previous PR I fixed some cases but broke others. So, new approach. Two phase algorithm: * First pass is forward data flow to determine all usages of macros. This is necessary because many of Meta's macros have variants that can be accessed via properties, eg you can do `macro(...)` but also `macro.variant(...)`. * Second pass is backwards data flow to find macro invocations (JSX and calls) and then merge their operands into the same scope as the macro call. Note that this required updating PromoteUsedTemporaries to avoid promoting macro calls that have interposing instructions between their creation and usage. Macro calls in general are pure so it should be safe to reorder them. In addition, we're now more precise about `<fb:plural>`, `<fbt:param>`, `fbt.plural()` and `fbt.param()`, which don't actually require all their arguments to be inlined. The whole point is that the plural/param value is an arbitrary value (along with a string name). So we no longer transitively inline the arguments, we just make sure that they don't get inadvertently promoted to named variables. One caveat: we actually don't do anything to treat macro functions as non-mutating, so `fbt.plural()` and friends (function form) may still sometimes group arguments just due to mutability inference. In a follow-up, i'll work to infer the types of nested macro functions as non-mutating. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34887). * #34900 * __->__ #34887
Configuration menu - View commit details
-
Copy full SHA for adbc32d - Browse repository at this point
Copy the full SHA adbc32dView commit details -
[compiler] Optimize props spread for common cases (#34900)
As part of the new inference model we updated to (correctly) treat destructuring spread as creating a new mutable object. This had the unfortunate side-effect of reducing precision on destructuring of props, though: ```js function Component({x, ...rest}) { const z = rest.z; identity(z); return <Stringify x={x} z={z} />; } ``` Memoized as the following, where we don't realize that `z` is actually frozen: ```js function Component(t0) { const $ = _c(6); let x; let z; if ($[0] !== t0) { const { x: t1, ...rest } = t0; x = t1; z = rest.z; identity(z); ... ``` #34341 was our first thought of how to do this (thanks @poteto for exploring this idea!). But during review it became clear that it was a bit more complicated than I had thought. So this PR explores a more conservative alternative. The idea is: * Track known sources of frozen values: component props, hook params, and hook return values. * Find all object spreads where the rvalue is a known frozen value. * Look at how such objects are used, and if they are only used to access properties (PropertyLoad/Destructure), pass to hooks, or pass to jsx then we can be very confident the object is not mutated. We consider any such objects to be frozen, even though technically spread creates a new object. See new fixtures for more examples. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34900). * __->__ #34900 * #34887Configuration menu - View commit details
-
Copy full SHA for c35f6a3 - Browse repository at this point
Copy the full SHA c35f6a3View commit details -
[Flight] Fix detached
ArrayBuffererror when streaming typed arrays (……#34849) Using `renderToReadableStream` in Node.js with binary data from `fs.readFileSync` (or `Buffer.allocUnsafe`) could cause downstream consumers (like compression middleware) to fail with "Cannot perform Construct on a detached ArrayBuffer". The issue occurs because Node.js uses an 8192-byte Buffer pool for small allocations (< 4KB). When React's `VIEW_SIZE` was 2KB, files between ~2KB and 4KB would be passed through as views of pooled buffers rather than copied into `currentView`. ByteStreams (`type: 'bytes'`) detach ArrayBuffers during transfer, which corrupts the shared Buffer pool and causes subsequent Buffer operations to fail. Increasing `VIEW_SIZE` from 2KB to 4KB ensures all chunks smaller than 4KB are copied into `currentView` (which uses a dedicated 4KB buffer outside the pool), while chunks 4KB or larger don't use the pool anyway. Thus no pooled buffers are ever exposed to ByteStream detachment. This adds 2KB memory per active stream, copies chunks in the 2-4KB range instead of passing them as views (small CPU cost), and buffers up to 2KB more data before flushing. However, it avoids duplicating large binary data (which copying everything would require, like the Edge entry point currently does in `typedArrayToBinaryChunk`). Related issues: - vercel/next.js#84753 - vercel/next.js#84858
Configuration menu - View commit details
-
Copy full SHA for dc485c7 - Browse repository at this point
Copy the full SHA dc485c7View commit details -
[DevTools] Tweak the rects design and create multi-environment color …
…scheme (#34880) <img width="1011" height="811" alt="Screenshot 2025-10-16 at 2 20 46 PM" src="https://github.com/user-attachments/assets/6dea3962-d369-4823-b44f-2c62b566c8f1" /> The selection is now clearer with a wider outline which spans the bounding box if there are multi rects. The color now gets darked changes on hover with a slight animation. The colors are now mixed from constants defined which are consistently used in the rects, the time span in the "suspended by" side bar and the scrubber. I also have constants defined for "server" and "other" debug environments which will be used in a follow up.
Configuration menu - View commit details
-
Copy full SHA for ef88c58 - Browse repository at this point
Copy the full SHA ef88c58View commit details -
[DevTools] Repeat the "name" if there's no short description in groups (
#34894) It looks weird when the row is blank when there's no short description for the entry in a group. <img width="328" height="436" alt="Screenshot 2025-10-17 at 12 25 30 AM" src="https://github.com/user-attachments/assets/12f5c55f-a37f-4b6d-913e-f763cec6b211" />
Configuration menu - View commit details
-
Copy full SHA for 724e7bf - Browse repository at this point
Copy the full SHA 724e7bfView commit details -
[DevTools] Highlight the rect when the corresponding timeline bean is…
… hovered (#34881) Stacked on #34880. In #34861 I removed the highlight of the real view when hovering the timeline since it was disruptive to stepping through the visuals. This makes it so that when we hover the timeline we highlight the rect with the subtle hover effect added in #34880. We can now just use the one shared state for this and don't need the CSS psuedo-selectors. <img width="603" height="813" alt="Screenshot 2025-10-16 at 3 11 17 PM" src="https://github.com/user-attachments/assets/a018b5ce-dd4d-4e77-ad47-b4ea068f1976" />
Configuration menu - View commit details
-
Copy full SHA for f970d5f - Browse repository at this point
Copy the full SHA f970d5fView commit details -
[DevTools] Don't highlight the root rect if no roots has unique suspe…
…nders (#34885) Stacked on #34881. We don't paint suspense boundaries if there are no suspenders. This does the same with the root. The root is still selectable so you can confirm but there's no affordance drawing attention to click the root. This could happen if you don't use the built-ins of React to load things like scripts and css. It would never happen in something like Next.js where code and CSS is loaded through React-native like RSC. However, it could also happen in the Activity scoped case when all resources are always loaded early.
Configuration menu - View commit details
-
Copy full SHA for 423c44b - Browse repository at this point
Copy the full SHA 423c44bView commit details -
[DevTools] Compute environment names for the timeline (#34892)
Stacked on #34885. This refactors the timeline to store not just an id but a complex object for each step. This will later represent a group of boundaries. Each timeline step is assigned an environment name. We pick the last environment name (assumed to have resolved last) from the union of the parent and child environment names. I.e. a child step is considered to be blocked by the parent so if a child isn't blocked on any environment name it still gets marked as the parent's environment name. In a follow up, I'd like to reorder the document order timeline based on environment names to favor loading everything in one environment before the next.
Configuration menu - View commit details
-
Copy full SHA for a083344 - Browse repository at this point
Copy the full SHA a083344View commit details -
[DevTools] Assign a different color and label based on environment (#…
…34893) Stacked on #34892. In the timeline scrubber each timeline entry gets a label and color assigned based on the environment computed for that step. In the rects, we find the timeline step that this boundary is part of and use that environment to assign a color. This is slightly different than picking from the boundary itself since it takes into account parent boundaries. In the "suspended by" section we color each entry individually based on the environment that spawned the I/O. <img width="790" height="813" alt="Screenshot 2025-10-17 at 12 18 56 AM" src="https://github.com/user-attachments/assets/c902b1fb-0992-4e24-8e94-a97ca8507551" />
Configuration menu - View commit details
-
Copy full SHA for 3a66917 - Browse repository at this point
Copy the full SHA 3a66917View commit details
Commits on Oct 18, 2025
-
Configuration menu - View commit details
-
Copy full SHA for 40c7a7f - Browse repository at this point
Copy the full SHA 40c7a7fView commit details
Commits on Oct 19, 2025
-
Resolve the .default export of a React.lazy as the canonical value (#…
…34906) For debug purposes this is the value that the `React.lazy` resolves to. It also lets us look at that value for descriptions like its name.
Configuration menu - View commit details
-
Copy full SHA for ec7d9a7 - Browse repository at this point
Copy the full SHA ec7d9a7View commit details -
[DevTools] Infer name from stack if it's the generic "lazy" name (#34907
) Stacked on #34906. Infer name from stack if it's the generic "lazy" name. It might be wrapped in an abstraction. E.g. `next/dynamic`. Also use the function name as a description of a resolved function value. <img width="310" height="166" alt="Screenshot 2025-10-18 at 10 42 05 AM" src="https://github.com/user-attachments/assets/c63170b9-2b19-4f30-be7a-6429bb3ef3d9" />
Configuration menu - View commit details
-
Copy full SHA for bf11d2f - Browse repository at this point
Copy the full SHA bf11d2fView commit details -
[Flight] Ignore bound-anonymous-fn resources as they're not considere…
…d I/O (#34911) When you create a snapshot from an AsyncLocalStorage in Node.js, that creates a new bound AsyncResource which everything runs inside of. https://github.com/nodejs/node/blob/3437e1c4bd529e51d96ea581b6435bbeb77ef524/lib/internal/async_local_storage/async_hooks.js#L61-L67 This resource is itself tracked by our async debug tracking as I/O. We can't really distinguish these in general from other AsyncResources which are I/O. However, by default they're given the name `"bound-anonymous-fn"` if you pass it an anonymous function or in the case of a snapshot, that's built-in: https://github.com/nodejs/node/blob/3437e1c4bd529e51d96ea581b6435bbeb77ef524/lib/async_hooks.js#L262-L263 We can at least assume that these are non-I/O. If you want to ensure that a bound resource is not considered I/O, you can ensure your function isn't assigned a name or give it this explicit name. The other issue here is that, the sequencing here is that we track the callsite of the `.snapshot()` or `.bind()` call as the trigger. So if that was outside of render for example, then it would be considered non-I/O. However, this might miss stuff if you resolve promises inside the `.run()` of the snapshot if the `.run()` call itself was spawned by I/O which should be tracked. Time will tell if those patterns appear. However, in cases like nested renders (e.g. Next.js's "use cache") then restoring it as if it was outside the parent render is what you do want.
Configuration menu - View commit details
-
Copy full SHA for 58bdc0b - Browse repository at this point
Copy the full SHA 58bdc0bView commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff 1324e1bb...58bdc0bb