Commit Graph

516 Commits

Author SHA1 Message Date
Luke Sandberg da7cbb13be [turbopack] Use Arrays instead of objects to bootstrap chunks (#81877)
### Improve performance of chunk bootstrapping leveraging arrays and maps

Currently we bootstrap the set of the modules in a chunk by passing an object to the runtime, this is suboptimal for a few reasons:

* The runtime just wants to iterate the object and copy it into a runtime datastructure and iterating objects is relatively slow
* The browser needs to spend time computing the 'shape' of this object and possibly changing internal representations

The solution to both these problems is of course, Arrays!.  so instead of an object like

```
{ [moduleId]: (__turbopack_context__) => {},...}
```

we use an array like this

```
[ moduleId, (__turbopack_context__) => {}]
```
* a non-empty sequence of module ids come first
   - we may have more than one to support scope hoisted modules
* the factory function

Because these objects are temporary this should make both constructing and iterating them faster.

Finally, in the runtime what we want to do is copy these modules into a global map that is represented as an `Object`.  Because we are constantly inserting new keys, this is a suboptimal case and a `Map` should be faster for both insertions and lookups.  So this adapts the moduleFactory type to use an es6 `Map` which is more optimized for this particular usecase.

Ideally we would do the same for the moduleCache but that would complicate `require.cache` usecases.  We could perhaps leverage a `Proxy` to maintain support but this is left as future work.

### Aside: why are arrays faster than objects?

Arrays are faster to parse because they incur fewer 'shape transitions' (background reading: https://v8.dev/blog/fast-properties vs https://v8.dev/blog/elements-kinds).  Basically for every new property v8 parses on the object literal it changes the hidden type (or 'shape').  For arrays the same thing happens but the process is much simpler as there is a fixed set of possible shapes and the browser will hit the terminal one after evaluating the second element.

Also arrays are simply faster to iterate than objects (but this is generally a non-controversial statement).

### Performance
Based on the `module-cost` benchmark this is a consistent win in all scenarios


| Scenario | Metric | HEAD (ms) | CHANGE (ms) | Delta (ms) | % Change |
|----------|--------|-----------|-------------|------------|----------|
| **Pages API ESM** | Load Duration | 33.46 | 27.87 | -5.59 | -16.7% ✅ |
| | Execution Duration | 63.22 | 62.54 | -0.68 | -1.1% ✅ |
| **Pages API CommonJS** | Load Duration | 44.11 | 33.76 | -10.35 | -23.5% ✅ |
| | Execution Duration | 32.05 | 25.70 | -6.35 | -19.8% ✅ |
| **Client ESM** | Load Duration | 34.74 | 27.65 | -7.09 | -20.4% ✅ |
| | Execution Duration | 46.13 | 40.35 | -5.78 | -12.5% ✅ |
| **Client CommonJS** | Load Duration | 30.43 | 24.48 | -5.95 | -19.6% ✅ |
| | Execution Duration | 25.15 | 17.18 | -7.97 | -31.7% ✅ |

### Risks

The biggest risk of this change is subtle bugs introduced due to `string` vs `number` confusion.   I found one subtle issue in how we rewrite `new Worker()` constructors, there could be more not covered by tests.
2025-08-02 11:47:23 -07:00
Tobias Koppers 825753a284 Turbopack: name the module factory function (#73553)
### What?

In development give the module factory a useful name, so it's clear in stack traces that this is the module evaluation part of the execution.

This also fixes some bugs with the stack trace parser, which seems to struggle if function names contain brackets. The automatically inferred function name would be the module id, which contains brackets.
2025-08-02 10:15:24 -07:00
Dario Lehmhus 2bb227ebee fix: turbopack loader ipc field mapping (#82112)
Co-authored-by: Dario Lehmhus <dario.lehmhus@ffw.com>
2025-07-31 14:24:18 +02:00
Josh Story 9484919a62 [CacheComponents] Use fallback params when validating dynamic routes in dev (#82069)
When validating a dynamic route in dev with Cache Components we must not
use more params than would be know at build time because we want to
ensure dev acts as an appropriate debug environment for build validation
issues. Any time a validation fails for reasons other than fallback
params it would have failed as well with fallback params. So we find the
smallest set of fallback params that would be used during the build
(which might be empty if you provide a complete set through
generateStaticParams) and we use that.
2025-07-28 16:13:20 -07:00
Sebastian "Sebbie" Silbermann c081cf7c88 [sourcemaps] Fully sourcemap stacks on the Server (#81904) 2025-07-28 11:25:23 +02:00
nextjs-bot 4b76801777 Upgrade React from 3d14fcf0-20250724 to 19baee81-20250725 (#82063)
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-07-25 22:22:03 +00:00
nextjs-bot 62856be393 Upgrade React from edac0dde-20250723 to 3d14fcf0-20250724 (#82020)
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-07-25 16:53:40 +02:00
nextjs-bot 4cf2da98ba Upgrade React from e9638c33-20250721 to 7513996f-20250722 (#81940)
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-07-23 11:59:19 +00:00
Jiachi Liu 9e7df6a52c [segment explorer] missing file suggestion (#81617) 2025-07-22 19:55:04 +02:00
Sebastian "Sebbie" Silbermann 0c0dc4865e [sourcemaps] Ensure codeframe when calling Client Functions from Server (#81918)
We just need to give a special name to that module so that we can ignore-list it later.

For Webpack I chose the same approach as https://github.com/vercel/next.js/pull/81229. Turbopack already sourcemapped the generated module.

Closes https://linear.app/vercel/issue/NAR-234

RSPack team is informed. Their compat layer doesn't implement `createFilename`
2025-07-22 18:29:39 +02:00
Sebastian "Sebbie" Silbermann 4699f8416e [test] Add dedicated test for error when client functions are called from server components (#81930)
We have a more specific one for `use cache`. This is the counterpart for the default environment.
2025-07-22 18:07:41 +02:00
Jiachi Liu afec9909a0 [segment explorer] hide for pages router (#81813)
Hide the segment explorer menu item in pages router 

Closes NEXT-4635
2025-07-18 23:07:49 +02:00
Wyatt Johnson 8abbb3dc2e refactor: rename experimental.dynamicIO to experimental.cacheComponents (#81562)
## What?

Rename `experimental.dynamicIO` to `experimental.cacheComponents` across
the Next.js codebase.

## Why?

We're going to be merging the functionality of the `ppr`, `dynamicIO`
and `useCache` experimental flags into the singular `cacheComponents`
flag to reduce complexity of the codebase and simplify adoption for
users wanting to experiment with experimental features.

## How?

- Renamed the configuration option from `experimental.dynamicIO` to
`experimental.cacheComponents`
- Added deprecation handling with automatic migration for the old option
name
- Updated all documentation, tests, and internal references
- Updated Rust code in SWC transforms and Turbopack
- Maintained backward compatibility with deprecation warnings

NAR-158
2025-07-17 19:30:28 -06:00
Jiachi Liu 10fb5bc683 [devtool] enable segment explorer by default (#81737)
Enable `experimental.devtoolSegmentExplorer` on canary by default and update snapshots
2025-07-17 13:01:50 +02:00
Sebastian "Sebbie" Silbermann 382b79bcc9 [sourcemaps] Consistent cursor columns (#81375)
Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
2025-07-16 20:45:34 +02:00
Jiachi Liu d04d65b5e6 [segment explorer] fix route url is missing cases (#81622) 2025-07-14 18:05:07 +00:00
Jiachi Liu 8f060ea25a [test] improve segment explorer tests snapshot (#81616)
Format line format: `<segment> [<files,>]`

This will help visualize the rendered segment explorer panel easier by checking the snapshot. e.g.

```
app/ [layout.tsx]
parallel-routes/ [layout.tsx, page.tsx]
@bar/ [layout.tsx, page.tsx]
@foo/ [layout.tsx, page.tsx]
```
2025-07-14 17:45:48 +02:00
Sebastian "Sebbie" Silbermann 4dd01eea2f [sourcemaps] Properly devirtualize rsc: URLs (#81554) 2025-07-11 21:45:49 +02:00
Jiachi Liu 27250721aa [segment explorer] redesign file pills and boundary trigger (#81302) 2025-07-11 15:42:57 +02:00
Sebastian "Sebbie" Silbermann 16c53236a7 Configure url for responses from patched fetch like the original response.url (#81507)
The main config that was missing is enumerability which is relevant for showing properties in the Chrome performance track and inferring shorthands.
2025-07-11 00:05:27 +02:00
Sebastian "Sebbie" Silbermann df2c2a8cf0 [sourcemaps] Stop sending stackframes in third-party chunks (#81344) 2025-07-10 23:29:58 +02:00
Hendrik Liebau b5ced37273 Name patched fetch function fetch (#81499)
This ensures that `fetch` is shown in stack traces (in collapsed
ignore-listed frames), instead of `patched`.
2025-07-10 15:48:42 +02:00
Jiachi Liu 2503c19dd0 [segment explorer] capture defined boundaries (#81232)
Capture defined boundaries (not-found / error / loading) and used to filter which one is available for boundary triggers

The trie will now hold all the defined boundaries, but what's different from the existing rendered boundaries is:

Here's the difference of new defined boundary trie nodes:
```
{
  type: "boundary:<type>"
  pagePath: "<pagePath>@boundary"
}
```
We add a `boundary:` prefix to determine if it's node representing existence;
We add a `@boundary` suffix to the filename cause the <pagePath> part is still need to use for indexing in the trie, but the `@boundary` doesn't matter yet. We'll remove it once we start using the file name in the dropdown panel

Closes NEXT-4330

### Example

When there's only one not-found.tsx, allow to trigger the not-found boundary and disable the rest.

https://github.com/user-attachments/assets/eb5c49a7-4fd2-496b-b778-fb66581908b3
2025-07-08 22:13:03 +02:00
nextjs-bot 9bbcfa2c14 Upgrade React from 5d87cd22-20250704 to a7a11657-20250708 (#81428)
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-07-08 19:09:00 +00:00
Sebastian "Sebbie" Silbermann 76d9ab8e4e [test] Improve React performance track tests (#81359) 2025-07-07 16:04:53 +02:00
Sebastian "Sebbie" Silbermann 39f5d0f32c [test] Dedicate suite for React's Server Request performance track (#81312)
We're testing this here since framework integration via `filterStackTrace` determines what React uses to determine the name of the Performance entry.
2025-07-06 11:47:17 +02:00
Hendrik Liebau 2d19dc626b [dynamicIO] Use owner stacks for dynamic validation errors (#81277)
With recent improvements in React, and after switching to the React
builds for Node.js in #81048, we can now generate better dynamic
validation error stacks in dev mode by utilizing owner stacks instead of
component stacks.

For async I/O, we're using the owner stack exclusively. For sync I/O
we're appending the owner stack to the call stack. In a future iteration
we might instead log the original error as-is where it occurs, and let
`patchErrorInspectNodeJS` handle the owner stack appending as a general
solution.

Additionally, we're now guiding users in the build-time error messages
to using `next dev` for further debugging of dynamic validation errors –
or, alternatively, using `next build --debug-prerender`.

closes NAR-149
2025-07-04 22:09:23 +02:00
Sebastian "Sebbie" Silbermann 7ed2d23ae5 [devtools] Omit line/col numbers for anonymous sources (#81223) 2025-07-03 15:23:27 +02:00
Vercel Release Bot 52b185d813 Upgrade React from 7216c0f0-20250630 to 73aa744b-20250702 (#81192)
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-07-02 18:16:23 +00:00
Jiachi Liu 1e9f598ba6 [segment explorer] refactor boundary trigger with ui primitives (#81147) 2025-07-02 18:48:03 +02:00
Sebastian "Sebbie" Silbermann 16e1e1455e [node-webstreams] Use React builds for Node.js (#81048)
Closes https://linear.app/vercel/issue/NEXT-4560/

React now exposes Web stream APIs in their Node.js builds so we can use the Node.js builds.

That enable us to use some of the Node.js goodies like `async_hooks` which is required for the React's experimental Server Requests track.

## Test plan

`next-server` runtimes did not increase bundle size. We even saved some in the `app-page` entries since we no longer have to bundle Edge and Node.js versions of React Server. We can rely solely on the Node.js variant of React Server.

A build of `test/e2e/app-dir/hello-world` shows no significant bundle size changes
2025-07-02 07:53:34 +02:00
Jiachi Liu 19bf594b60 Revert "[devtool] merge segment explorer flag into panel ui flag (#81085)" (#81131)
Reverts #81085 to keep the flags separate so can test separately
2025-07-01 19:25:00 +02:00
Jiachi Liu 13401d8fd8 [devtool] merge segment explorer flag into panel ui flag (#81085) 2025-07-01 15:35:21 +02:00
Jiachi Liu 82c85a5b7b [segment explorer] trigger boundary initial support (#80948) 2025-06-30 16:54:46 +02:00
Hendrik Liebau 36930024ff Ignore JSON.parse <anonymous> (0:0) stack frames in test snapshots (#81044)
These frames will be ignore-listed soon. Until then, we remove them from the test snapshots, because their occurrence seems to be non-deterministic. They come from React's RSC parsing.
2025-06-29 15:35:04 -04:00
Jiachi Liu 33477b7e64 [segment-explorer] display the builtin conventions (#80961)
Track built-in conventions in segment explorer. The default `global-not-found.js` and `global-error.js` will be displayed.
Their style will be different to the others, we'll follow up in the later PRs.

Closes NEXT-4576
2025-06-27 16:41:07 +02:00
Jiachi Liu 71cdce68e0 [refactor] group the built-in conventions (#80957)
Group all the built-in conventions into `src/client/components/builtin` with the actual same name of the conventions they represent.

e.g. 
The default `not-found.js` is `next/dist/client/compoents/builtin/not-found.js`;
The default `global-error.js` is `next/dist/client/compoents/builtin/global-error.js`;

This give us an easier way to track all the builtin conventions. This is also the preparation work for #80961 where we display the builtin conventions in the segment explorer.
2025-06-26 23:36:57 +02:00
Vercel Release Bot 65e76eafbe Upgrade React from 197d6a04-20250424 to fa3feba6-20250623 (#80804)
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-06-26 16:12:52 +02:00
Jiachi Liu c54cc01902 [segment explorer] display default page in segment explorer (#80716) 2025-06-23 23:18:09 +02:00
Jiachi Liu 8324d8108c [segment explorer] handle custom error boundary (#80714)
Display custom error boundary `error.js` in segement explorer when it's rendered

![image](https://github.com/user-attachments/assets/4abad442-0703-4609-8202-b4f41f007afe)

Closes NEXT-4331
2025-06-23 22:23:47 +02:00
Jiachi Liu 9d4239a150 [segment explorer] handle display loading (#80698) 2025-06-23 21:03:17 +02:00
Jiachi Liu 6e508d4f93 [segment explorer] display navigation error boundaries (#80691) 2025-06-23 18:08:02 +02:00
Jiachi Liu 3981cccbe3 [segment explorer] handle custom global-error segment (#80685) 2025-06-23 17:36:20 +02:00
Jiachi Liu 5771ce12f8 [segment explorer] handle builtin not-found (#80607) 2025-06-23 15:23:43 +02:00
Jiachi Liu 9df0c8763c [segment explorer] handle edge and pages router (#80668) 2025-06-23 14:06:01 +02:00
Sebastian "Sebbie" Silbermann da46d66667 Downgrade React from 79d9aed7-20250620 to 197d6a04-20250424 (#80762) 2025-06-22 09:07:44 +00:00
Sebastian "Sebbie" Silbermann 6a0b7e9059 Upgrade React from 197d6a04-20250424 to 79d9aed7-20250620 (#79477) 2025-06-20 15:47:45 +02:00
Jiachi Liu f3d6af9525 [segment explorer] single row layout segment (#80576) 2025-06-18 16:16:19 +02:00
Jiachi Liu f8add0d9ff [segment explorer] fix soft navigation case (#80443) 2025-06-12 13:10:33 +02:00
Sebastian "Sebbie" Silbermann ae1f0be351 [segment-explorer] Signal updates to React (#80316)
We never actually invoked the listeners attached by React. Updates only worked on soft-navigation because we also re-render the DevOverlayRoot and don't bail out anywhere at the moment.

Just invoking the listeners is not sufficient after https://github.com/vercel/next.js/pull/79699 since userspace and dev-overlay would read different versions of `listeners`. I ported the segment explorer into the new folder structure. Updates now flow through the `dispatcher` and then invoking the listeners actually works. Though mid term we should move the segment tree into actual React tree to get rid of the sync updates.

I also noticed that we're missing an implementation for a remove operation which is required to show the correct state during soft navigations.
2025-06-12 12:48:08 +02:00