mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
(#93807) ## What Stop pinning compiled chunk source on `EcmascriptBuildNodeChunkVersion`. The struct previously held a `Vec<ReadRef<CodeAndIds>>` for every module in the chunk, even though the HMR update path only needs the bytes for the *changed* subset and the bytes are already on disk. That field was also forcing the upstream `CodeAndIds` / `BatchGroupCodeAndIds` tasks to stay `serialization = "skip"`, so warm restarts had to re-walk every module and re-hash its source to rebuild `entries_hashes`. This change mirrors the browser-side pattern: a new `EcmascriptBuildNodeChunkContentEntries` task lives on the chunk content and holds `ResolvedVc<Code>` + `ResolvedVc<u64>` per module. The version struct shrinks to `{ chunk_path, minify_type, entries_hashes }`, drops `serialization = "skip"`, and switches `chunk_path` from `String` to `RcStr`. `update_ecmascript_node_chunk_content` now resolves entries lazily, only when an added or modified module actually needs its code shipped. ## Why Two wins, both for dev sessions starting against a warm filesystem cache: - **Memory.** The version no longer transitively pins every module's compiled `Rope` in heap — those bytes can stay on disk until HMR actually needs them. - **Warm-restart CPU.** `entries_hashes` is sourced from the per-module `Code::source_code_hash()` task (already cached) and the version itself now round-trips through the persistent cache, so we don't re-hash anything on warm start. The HMR payload shape is unchanged. ## Perf This should speed up warm builds a bit but the major benefit is not recomputing node outputs and keeping them in ram measuring v0 after loading the main route Branch: Cold: 12.3G Warm: 7.34G Canary: Cold 12.3G Warm: 8.5G The trace file confirms the recomputations are gone and the heap measurements confirm we trimming ~1.1g of ram Using the devlow benchmarks i was able to confirm a possible small progression ``` # canary chat dev startup build=warm: root page = 23.96 s (from root page/start) chat dev startup build=warm: root page = 21.21 s (from root page/start) chat dev startup build=warm: root page = 22.70 s (from root page/start) # branch chat dev startup build=warm: root page = 20.94 s (from root page/start) chat dev startup build=warm: root page = 19.43 s (from root page/start) chat dev startup build=warm: root page = 23.49 s (from root page/start) ``` ## Tests I added a new integration test to ensure we don't accidentally regress here. Which confirms that 'clean warm builds' run nothing and 'clean warm dev sessions' just set up HMR session infra <!-- NEXT_JS_LLM_PR -->
42 lines
1.0 KiB
TOML
42 lines
1.0 KiB
TOML
[package]
|
|
name = "turbopack-nodejs"
|
|
version = "0.1.0"
|
|
description = "TBD"
|
|
license = "MIT"
|
|
edition = "2024"
|
|
autobenches = false
|
|
|
|
[lib]
|
|
bench = false
|
|
|
|
[features]
|
|
# enable "HMR" for embedded assets
|
|
dynamic_embed_contents = ["turbo-tasks-fs/dynamic_embed_contents"]
|
|
# enable test utilities such as `RuntimeType::Dummy`
|
|
test = ["turbopack-ecmascript-runtime/test"]
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[dependencies]
|
|
anyhow = { workspace = true }
|
|
bincode = { workspace = true }
|
|
either = { workspace = true }
|
|
indoc = { workspace = true }
|
|
serde = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
serde_qs = { workspace = true }
|
|
tracing = { workspace = true }
|
|
urlencoding = { workspace = true }
|
|
|
|
turbo-bincode = { workspace = true }
|
|
turbo-rcstr = { workspace = true }
|
|
turbo-tasks = { workspace = true }
|
|
turbo-tasks-fs = { workspace = true }
|
|
turbo-tasks-hash = { workspace = true }
|
|
turbopack = { workspace = true }
|
|
turbopack-core = { workspace = true }
|
|
turbopack-ecmascript = { workspace = true }
|
|
turbopack-ecmascript-runtime = { workspace = true }
|
|
|