Skip to content

[turbopack] Simplify JS ChunkItem with a single impl in most cases#89548

Merged
mmastrac merged 6 commits into
canaryfrom
mmastrac/simplify-chunk-item
Feb 12, 2026
Merged

[turbopack] Simplify JS ChunkItem with a single impl in most cases#89548
mmastrac merged 6 commits into
canaryfrom
mmastrac/simplify-chunk-item

Conversation

@mmastrac

@mmastrac mmastrac commented Feb 5, 2026

Copy link
Copy Markdown
Contributor

What

Removes the vast majority of ChunkItem implementations in favour of one EcmascriptModuleChunkItem.

Why

Almost all of the ChunkItem implementations are trivial and were, for the most part, just places where additional traits could be implemented.

By removing all of the various, trivial implementations, this might open up opportunities to better implement other features across the entire codebase.

How

Most chunk items are migrated over to EcmascriptModuleChunkItem. The EcmascriptChunkPlaceable trait gains three new methods that modules can optionally override:

  • chunk_item_content() - generates the chunk item's JavaScript code
  • chunk_item_content_ident() - returns the content identity for cache invalidation
  • chunk_item_output_assets() - returns output assets the chunk item depends on

The generic EcmascriptModuleChunkItem delegates to these trait methods, eliminating the need for per-module wrapper structs.

Next Steps

This exposes a fairly obvious next step, which is to elide ChunkItem completely, as most as_chunk_item() functions are now just trivial calls to ecmascript_chunk_item(Vc::upcast(*self), module_graph, *chunking_context).

@nextjs-bot nextjs-bot added created-by: Turbopack team PRs by the Turbopack team. Turbopack Related to Turbopack with Next.js. labels Feb 5, 2026
@mmastrac mmastrac marked this pull request as ready for review February 5, 2026 18:15
@mmastrac mmastrac marked this pull request as draft February 5, 2026 18:16

mmastrac commented Feb 5, 2026

Copy link
Copy Markdown
Contributor Author

@nextjs-bot

nextjs-bot commented Feb 5, 2026

Copy link
Copy Markdown
Contributor

Tests Passed

@codspeed-hq

codspeed-hq Bot commented Feb 5, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 17 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing mmastrac/simplify-chunk-item (1aa04f8) with canary (6627734)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@nextjs-bot

nextjs-bot commented Feb 5, 2026

Copy link
Copy Markdown
Contributor

Stats from current PR

✅ No significant changes detected

📊 All Metrics
📖 Metrics Glossary

Dev Server Metrics:

  • Listen = TCP port starts accepting connections
  • First Request = HTTP server returns successful response
  • Cold = Fresh build (no cache)
  • Warm = With cached build artifacts

Build Metrics:

  • Fresh = Clean build (no .next directory)
  • Cached = With existing .next directory

Change Thresholds:

  • Time: Changes < 50ms AND < 10%, OR < 2% are insignificant
  • Size: Changes < 1KB AND < 1% are insignificant
  • All other changes are flagged to catch regressions

⚡ Dev Server

Metric Canary PR Change Trend
Cold (Listen) 455ms 455ms ▁▁▁▁▁
Cold (Ready in log) 449ms 449ms ▁▁▂▁▂
Cold (First Request) 856ms 842ms ▁▄▅▁▄
Warm (Listen) 456ms 456ms ▁▁▁▁▁
Warm (Ready in log) 447ms 446ms ▁▁▁▁▁
Warm (First Request) 342ms 343ms ▁▂▁▁▁
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 456ms 457ms █▁▁▁█
Cold (Ready in log) 457ms 457ms █▃▃▁█
Cold (First Request) 1.885s 1.886s █▂▂▁█
Warm (Listen) 455ms 455ms █▁▁▁█
Warm (Ready in log) 457ms 456ms █▃▃▁█
Warm (First Request) 1.873s 1.890s █▂▂▁█

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 4.229s 4.187s ▁▁▁▂▁
Cached Build 4.249s 4.229s ▁▁▁▂▁
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 14.865s 14.952s █▁▁▁█
Cached Build 14.966s 14.994s █▁▁▁█
node_modules Size 472 MB 472 MB █████
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles: **437 kB** → **437 kB** ✅ -2 B

81 files with content-based hashes (individual files not comparable between builds)

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 765 B 761 B
Total 765 B 761 B ✅ -4 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 448 B 451 B
Total 448 B 451 B ⚠️ +3 B

📦 Webpack

Client

Main Bundles
Canary PR Change
5528-HASH.js gzip 5.47 kB N/A -
6280-HASH.js gzip 57 kB N/A -
6335.HASH.js gzip 169 B N/A -
912-HASH.js gzip 4.53 kB N/A -
e8aec2e4-HASH.js gzip 62.5 kB N/A -
framework-HASH.js gzip 59.7 kB 59.7 kB
main-app-HASH.js gzip 256 B 253 B 🟢 3 B (-1%)
main-HASH.js gzip 39.1 kB 39.1 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
262-HASH.js gzip N/A 4.53 kB -
2889.HASH.js gzip N/A 169 B -
5602-HASH.js gzip N/A 5.49 kB -
6948ada0-HASH.js gzip N/A 62.5 kB -
9544-HASH.js gzip N/A 57.7 kB -
Total 230 kB 231 kB ⚠️ +635 B
Polyfills
Canary PR Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Total 39.4 kB 39.4 kB
Pages
Canary PR Change
_app-HASH.js gzip 194 B 194 B
_error-HASH.js gzip 183 B 180 B 🟢 3 B (-2%)
css-HASH.js gzip 331 B 330 B
dynamic-HASH.js gzip 1.81 kB 1.81 kB
edge-ssr-HASH.js gzip 256 B 256 B
head-HASH.js gzip 351 B 352 B
hooks-HASH.js gzip 384 B 383 B
image-HASH.js gzip 580 B 581 B
index-HASH.js gzip 260 B 260 B
link-HASH.js gzip 2.49 kB 2.49 kB
routerDirect..HASH.js gzip 320 B 319 B
script-HASH.js gzip 386 B 386 B
withRouter-HASH.js gzip 315 B 315 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Total 7.97 kB 7.97 kB ✅ -1 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 126 kB 126 kB
page.js gzip 249 kB 250 kB
Total 375 kB 376 kB ⚠️ +391 B
Middleware
Canary PR Change
middleware-b..fest.js gzip 612 B 614 B
middleware-r..fest.js gzip 156 B 155 B
middleware.js gzip 33.3 kB 33.2 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 34.9 kB 34.8 kB ✅ -158 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 733 B 735 B
Total 733 B 735 B ⚠️ +2 B
Build Cache
Canary PR Change
0.pack gzip 3.84 MB 3.85 MB 🔴 +10.4 kB (+0%)
index.pack gzip 104 kB 103 kB 🟢 1.5 kB (-1%)
index.pack.old gzip 103 kB 104 kB
Total 4.05 MB 4.05 MB ⚠️ +9.74 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 316 kB 316 kB
app-page-exp..prod.js gzip 168 kB 168 kB
app-page-tur...dev.js gzip 315 kB 315 kB
app-page-tur..prod.js gzip 167 kB 167 kB
app-page-tur...dev.js gzip 312 kB 312 kB
app-page-tur..prod.js gzip 166 kB 166 kB
app-page.run...dev.js gzip 312 kB 312 kB
app-page.run..prod.js gzip 166 kB 166 kB
app-route-ex...dev.js gzip 70.5 kB 70.5 kB
app-route-ex..prod.js gzip 49 kB 49 kB
app-route-tu...dev.js gzip 70.5 kB 70.5 kB
app-route-tu..prod.js gzip 49 kB 49 kB
app-route-tu...dev.js gzip 70.1 kB 70.1 kB
app-route-tu..prod.js gzip 48.8 kB 48.8 kB
app-route.ru...dev.js gzip 70.1 kB 70.1 kB
app-route.ru..prod.js gzip 48.8 kB 48.8 kB
dist_client_...dev.js gzip 324 B 324 B
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
dist_client_...dev.js gzip 317 B 317 B
pages-api-tu...dev.js gzip 43.2 kB 43.2 kB
pages-api-tu..prod.js gzip 32.9 kB 32.9 kB
pages-api.ru...dev.js gzip 43.2 kB 43.2 kB
pages-api.ru..prod.js gzip 32.8 kB 32.8 kB
pages-turbo....dev.js gzip 52.5 kB 52.5 kB
pages-turbo...prod.js gzip 39.4 kB 39.4 kB
pages.runtim...dev.js gzip 52.5 kB 52.5 kB
pages.runtim..prod.js gzip 39.4 kB 39.4 kB
server.runti..prod.js gzip 62.7 kB 62.7 kB
Total 2.8 MB 2.8 MB ⚠️ +1 B

@mmastrac mmastrac force-pushed the mmastrac/simplify-chunk-item branch 3 times, most recently from 5ae8915 to c242537 Compare February 9, 2026 20:14
@mmastrac mmastrac changed the title Experiment: simplify chunk item with a single impl [turbopack] Simplify ChunkItem with a single impl in most cases Feb 9, 2026
@mmastrac mmastrac marked this pull request as ready for review February 9, 2026 20:58
@mmastrac mmastrac requested a review from a team February 9, 2026 20:58
@mmastrac mmastrac force-pushed the mmastrac/simplify-chunk-item branch from c242537 to 0ee40d8 Compare February 9, 2026 21:23
Comment thread crates/next-core/src/next_server_utility/server_utility_module.rs
fn content(self: Vc<Self>) -> Vc<EcmascriptChunkItemContent> {
panic!("content() should not be called");
fn get_exports(&self) -> Vc<EcmascriptExports> {
// Merged modules inherit exports from their entry points

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this wouldn't be correct

i think it is ok, but a bail or a panic might be more useful

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, should be a panic.
get_exports should never be called on merged modules

@lukesandberg lukesandberg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess after seeing this i do wonder if a macro for implementing chunk_item would be the better solution. The tradeoff is really the chunk_item_content api vs the EcmascriptChunkItem trait implementation being customized

Comment thread turbopack/crates/turbopack-ecmascript/src/chunk/item.rs
Comment thread turbopack/crates/turbopack-ecmascript/src/chunk/item.rs Outdated
Comment thread turbopack/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs
Comment thread crates/next-core/src/next_dynamic/dynamic_module.rs Outdated
Comment thread turbopack/crates/turbopack-browser/src/chunking_context.rs Outdated
Comment thread turbopack/crates/turbopack-browser/src/chunking_context.rs Outdated
Comment thread turbopack/crates/turbopack-ecmascript/src/async_chunk/module.rs
Comment thread turbopack/crates/turbopack-ecmascript/src/async_chunk/module.rs
Comment thread turbopack/crates/turbopack-ecmascript/src/inlined_bytes_module.rs Outdated
Comment thread crates/next-core/src/next_server_utility/server_utility_module.rs
@mischnic mischnic changed the title [turbopack] Simplify ChunkItem with a single impl in most cases [turbopack] Simplify JS ChunkItem with a single impl in most cases Feb 10, 2026
@mmastrac mmastrac force-pushed the mmastrac/simplify-chunk-item branch from 0ee40d8 to 6afd193 Compare February 11, 2026 20:35
@mmastrac mmastrac force-pushed the mmastrac/simplify-chunk-item branch from 6afd193 to becdc84 Compare February 11, 2026 20:43
…thod

The ChunkableModuleReference trait was removed in this PR. References that
need to be chunkable now implement the chunking_type() method on
ModuleReference to return Some(ChunkingType::Parallel { ... }) instead.
@mmastrac mmastrac merged commit ff63646 into canary Feb 12, 2026
164 checks passed
@mmastrac mmastrac deleted the mmastrac/simplify-chunk-item branch February 12, 2026 16:56
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Feb 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

created-by: Turbopack team PRs by the Turbopack team. locked Turbopack Related to Turbopack with Next.js.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants