Commit f0c1ffc
authored
Remove ineffective turbo-tasks (#91341)
## Remove ineffective turbo-tasks
Identifies and removes turbo-tasks functions where the task overhead exceeds the value they provide. Each turbo-task carries ~4-6μs execution overhead per miss and ~200-500ns per cache hit, plus allocations and bookkeeping.
### What?
Removes 22 `#[turbo_tasks::function]` implementations across resolve plugins, chunk items, and resolve-result helpers — converting them to plain methods or inlining their work. Changes fall into a few buckets:
- **ResolvePlugin condition handling** (`AfterResolvePluginCondition::matches`, `BeforeResolvePluginCondition::matches`, `after_resolve_condition`, `before_resolve_condition`): conditions now store the resolved `Glob` as a `ReadRef<Glob>` on the plugin struct at construction, so `matches` is a pure sync function and the per-plugin `*_resolve_condition` getters are trivial field reads (no longer turbo-tasks). The `after_resolve` / `before_resolve` hooks themselves stay as `#[turbo_tasks::function]` — they synthesize virtual sources/modules and need memoization on `(self, lookup_path, reference_type, request)` to avoid distinct cells producing duplicate module-graph idents.
- The basic theory here is that the right level of caching is at `resolve` and at the hook bodies themselves, not the conditions or condition getters.
- `AfterResolvePluginCondition` and `BeforeResolvePluginCondition` are marked `serialization = "none"` because `ReadRef` cannot be persisted; plugin construction is cheap enough to re-derive on restore.
- **ChunkItem trait methods** (`chunking_context`, `ty`, `content_with_async_module_info`): returned constants or simple field reads, zero cache hits and no `.await` calls (no invalidation value).
- **ResolveResult / ModuleResolveResult helpers** (`primary_modules`, `first_module`, `first_source`, `primary_sources`, `is_unresolvable`, `primary_output_assets`): simple iterators over already-resolved data; converted to plain methods. Added a `Duplicate(usize)` variant to `ModuleResolveResultItem` to handle dedup at construction time instead of in a separate task.
- The basic idea here is that it is reasonable to consume `ResolveResult/ModuleResolveResult` monolithically, and we get little to no benefit from fine grained access. e.g. `is_unresolved()` in theory that is a valuable turbotask, but since it rarely changes but generally if we change how we resolve an import then we have to regenerate code, so saving a few boolean conditions is unlikely to be very valuable.
- Misc: `EcmascriptModuleAsset::analyze`, `is_types_resolving_enabled`, `next_server::resolve::condition`.
### Impact (vercel-site build, dev first-compile)
| Metric | Before | After | Δ |
|---|---:|---:|---:|
| Total cache hits | 30,885,827 | 29,201,314 | −1,684,513 |
| Total cache misses | 6,473,123 | 5,953,626 | **−519,497** |
| Overall hit rate | 82.67% | 83.06% | +0.39 pp |
| Registered task functions | 1,294 | 1,272 | −22 |
The 22 removed tasks were collectively responsible for ~519K misses per build — each miss previously paying the full execution overhead. Most of the work from `EcmascriptModuleAsset::analyze` naturally migrated into `analyze_ecmascript_module` (the task it was wrapping; +129K hits there).
### On-disk cache size (persistent caching)
Each removed task also stops allocating cache cells on disk. Measured on the same vercel-site build with `.next/cache/turbopack` (persistent cache enabled):
| | Size |
|---|---:|
| canary | 2.56 GiB |
| this branch | 2.46 GiB |
| **saved** | **~100 MiB (−3.81%)** |
### Build-time wall clock and peak memory
Ran `pnpm next build --experimental-build-mode=compile` 5 times on each branch
**Peak RSS — clear reduction:**
| | canary | branch | Δ |
|---|---:|---:|---:|
| min | 19.18 GiB | 18.94 GiB | |
| **median** | **19.22 GiB** | **19.01 GiB** | **−217 MiB (−1.10%)** |
| mean | 19.21 GiB | 19.02 GiB | −199 MiB (−1.01%) |
| max | 19.23 GiB | 19.13 GiB | |
Every branch run has lower RSS than every canary run — the distributions don't overlap. Welch's t = −6.03.
**Wall time — no measurable change:**
| | canary | branch | Δ |
|---|---:|---:|---:|
| min | 62.03s | 60.78s | |
| **median** | **62.61s** | **62.65s** | **+0.04s (+0.06%)** |
| mean | 62.83s | 63.80s | +0.96s (+1.53%) |
| max | 64.25s | 68.23s | |
| stddev | 0.84s | 3.42s | |
Median is flat. The mean difference is within noise (Welch's t = +0.61, n = 5). Branch run-to-run variance is higher — one 68.23s outlier pulls the mean up — so this is neither a regression nor a measurable speedup at this sample size.
<!-- NEXT_JS_LLM_PR -->1 parent e83bc93 commit f0c1ffc
44 files changed
Lines changed: 931 additions & 425 deletions
File tree
- crates
- next-api/src
- next-core/src
- next_client_reference/ecmascript_client_reference
- next_client
- next_font/local
- next_server
- turbopack
- crates
- turbo-tasks-fs/src
- turbopack-browser/src
- turbopack-cli-utils/src
- turbopack-cli/src
- build
- dev
- turbopack-core/src
- chunk
- chunking
- introspect
- module_graph
- reference
- resolve
- turbopack-css/src
- references
- turbopack-ecmascript/src
- chunk
- references
- esm
- turbopack-node/src/transforms
- turbopack-resolve/src
- turbopack/src
- scripts
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
860 | 860 | | |
861 | 861 | | |
862 | 862 | | |
863 | | - | |
864 | 863 | | |
865 | 864 | | |
866 | 865 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
242 | 242 | | |
243 | 243 | | |
244 | 244 | | |
| 245 | + | |
245 | 246 | | |
246 | 247 | | |
247 | 248 | | |
248 | | - | |
| 249 | + | |
249 | 250 | | |
250 | 251 | | |
251 | 252 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
566 | 566 | | |
567 | 567 | | |
568 | 568 | | |
| 569 | + | |
569 | 570 | | |
570 | 571 | | |
571 | 572 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
43 | | - | |
44 | 43 | | |
45 | 44 | | |
46 | 45 | | |
| |||
Lines changed: 7 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
320 | 321 | | |
321 | 322 | | |
322 | 323 | | |
323 | | - | |
324 | 324 | | |
325 | 325 | | |
326 | 326 | | |
327 | 327 | | |
328 | | - | |
329 | 328 | | |
330 | 329 | | |
331 | 330 | | |
| |||
336 | 335 | | |
337 | 336 | | |
338 | 337 | | |
| 338 | + | |
339 | 339 | | |
340 | 340 | | |
341 | | - | |
342 | | - | |
343 | | - | |
344 | | - | |
345 | | - | |
346 | | - | |
347 | | - | |
| 341 | + | |
348 | 342 | | |
349 | 343 | | |
350 | 344 | | |
351 | | - | |
| 345 | + | |
352 | 346 | | |
| 347 | + | |
| 348 | + | |
353 | 349 | | |
| 350 | + | |
354 | 351 | | |
355 | 352 | | |
356 | 353 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
| 55 | + | |
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
58 | 59 | | |
59 | 60 | | |
60 | | - | |
61 | | - | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
62 | 69 | | |
63 | 70 | | |
64 | 71 | | |
65 | 72 | | |
66 | 73 | | |
67 | | - | |
68 | 74 | | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
| 75 | + | |
73 | 76 | | |
74 | 77 | | |
75 | 78 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1269 | 1269 | | |
1270 | 1270 | | |
1271 | 1271 | | |
1272 | | - | |
| 1272 | + | |
1273 | 1273 | | |
1274 | 1274 | | |
1275 | 1275 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
46 | 45 | | |
47 | 46 | | |
| 47 | + | |
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
| 53 | + | |
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
58 | | - | |
| 57 | + | |
| 58 | + | |
59 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
60 | 65 | | |
61 | 66 | | |
| 67 | + | |
62 | 68 | | |
63 | | - | |
| 69 | + | |
64 | 70 | | |
65 | 71 | | |
66 | 72 | | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | 73 | | |
76 | 74 | | |
77 | | - | |
78 | 75 | | |
79 | | - | |
| 76 | + | |
80 | 77 | | |
81 | 78 | | |
82 | 79 | | |
| |||
85 | 82 | | |
86 | 83 | | |
87 | 84 | | |
88 | | - | |
| 85 | + | |
89 | 86 | | |
90 | 87 | | |
91 | 88 | | |
| |||
112 | 109 | | |
113 | 110 | | |
114 | 111 | | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
| 112 | + | |
119 | 113 | | |
120 | 114 | | |
121 | 115 | | |
| |||
214 | 208 | | |
215 | 209 | | |
216 | 210 | | |
217 | | - | |
| 211 | + | |
218 | 212 | | |
219 | 213 | | |
220 | 214 | | |
| |||
230 | 224 | | |
231 | 225 | | |
232 | 226 | | |
233 | | - | |
| 227 | + | |
234 | 228 | | |
235 | 229 | | |
236 | 230 | | |
| |||
288 | 282 | | |
289 | 283 | | |
290 | 284 | | |
291 | | - | |
| 285 | + | |
292 | 286 | | |
293 | 287 | | |
294 | 288 | | |
| |||
0 commit comments