Skip to content

fix(pack): use short hashes for production client chunks - #3342

Merged
fireairforce merged 6 commits into
nextfrom
zoomdong/short-production-chunk-names
Sep 9, 2026
Merged

fireairforce merged 6 commits into
nextfrom
zoomdong/short-production-chunk-names

Conversation

@fireairforce

@fireairforce fireairforce commented Sep 9, 2026 •

Copy link
Copy Markdown
Member

Summary

Production client builds currently keep module paths in JS/CSS chunk filenames, which can exceed deployment URL limits once a host and public path are prepended. Enable upstream Turbopack's 13-character base38 content-hash naming by default: ordinary JS chunks become <hash>.js, and entry runtimes become turbopack-<hash>.js.

Explicit filename templates still take precedence, and development builds retain readable names. Update the affected production snapshots, make assertions independent of generated filenames, and add long-path/template regression cases. Document the default change and output.filename: "[name].js" for consumers that need stable entry names. Static assets, copied files, server builds, and library builds keep their existing naming rules; full URL limits still depend on the deployment prefix.

Includes the merged utooland/next.js#190 via submodule commit fb5c6e39ce1a935a3d9cf7bd8cfe70f1e84f048b. Its tree is identical to the previously tested PR head. Submodule pointer updates are recorded separately from the Pack integration and snapshots. Most changed files are generated snapshot renames and updated references.

Test Plan

  • Latest-base isolated checkout: cargo test -p pack-tests — 143 passed, no failures.

  • cargo clippy --all-targets -- -D warnings --no-deps; targeted turbopack-browser Clippy check passed during implementation.

  • Rust formatting, tombi format --check, biome ci, and typos passed.

  • New regressions cover long-path production JS/CSS, source-map references, and explicit filename templates. Existing development, worker, external, server/library and multi-entry cases pass.

  • Browser smoke test with a rebuilt binding: entry, dynamic JS/CSS, image and Worker loading pass without runtime errors. An identical rebuild preserves paths and bytes; editing a lazy module changes hashes and keeps runtime references valid.

  • Review follow-up: default chunk hashes honor the configured context salt and clamp requested lengths to the available 25 base38 characters.

  • Regression coverage lives in Utoo crates/pack-tests/tests/chunk_hashing.rs: JS/CSS salt changes and stability, preserved prefix/extension, and 26/255-character requests. The new test and all 143 existing snapshot tests pass; full-workspace and targeted browser Clippy and formatting checks pass.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-09T06:28:30.039111Z 7d8c979 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@fireairforce
fireairforce force-pushed the zoomdong/short-production-chunk-names branch from 765f832 to 61c2c76 Compare September 9, 2026 06:58
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

📊 Performance Benchmark Report (with-antd)

Utoopack Performance Report

Report ID: utoopack_performance_report_20260909_071554
Generated: 2026-09-09 07:15:54
Trace File: trace_antd.json (0.3GB, 0.82M spans)
Test Project: examples/with-antd


Executive Summary

Metric Value Assessment
Total Wall Time 6,387.7 ms Baseline
Total Thread Work (de-duped) 19,308.0 ms Non-overlapping busy time
Effective Parallelism 3.0x thread_work / wall_time
Working Threads 9 Threads with actual spans
Thread Utilization 33.6% ⚠️ Suboptimal
Total Spans 819,696 All B/E + X events
Meaningful Spans (>= 10us) 219,615 (26.8% of total)
Tracing Noise (< 10us) 600,081 (73.2% of total)

Build Phase Timeline

Shows when each build phase is active and how much CPU it consumes.
Self-Time is the time spent exclusively in that phase (excluding children).

Phase Spans Inclusive (ms) Self-Time (ms) Wall Range (ms)
Resolve 50,040 6,895.2 1,890.5 3,164.5
Parse 8,186 1,336.8 995.5 5,869.5
Analyze 139,281 39,884.3 9,021.2 5,779.1
Chunk 5,838 5,932.3 962.5 2,377.0
Codegen 12,942 2,406.1 1,489.9 2,058.7
Emit 31 40.9 20.5 8.0
Other 3,297 6,070.5 3,352.3 6,387.7

Workload Distribution by Diagnostic Tier

Category Spans Inclusive (ms) % Work Self-Time (ms) % Self
P0: Scheduling & Resolution 189,802 47,298.3 245.0% 11,116.7 57.6%
P1: I/O & Heavy Tasks 2,910 111.3 0.6% 90.9 0.5%
P2: Architecture (Locks/Memory) 0 0.0 0.0% 0.0 0.0%
P3: Asset Pipeline 25,621 9,718.1 50.3% 3,468.1 18.0%
P4: Bridge/Interop 0 0.0 0.0% 0.0 0.0%
Other 1,282 5,438.4 28.2% 3,056.6 15.8%

Top 20 Tasks by Self-Time

Self-time is the exclusive duration: time spent in the task itself, not in sub-tasks.
This is the most accurate indicator of where CPU cycles are actually spent.

Self (ms) Inclusive (ms) Count Avg Self (us) P95 Self (ms) Max Self (ms) % Work Task Name Top Caller
4,717.1 25,074.6 96,063 49.1 0.1 10.1 24.4% module module (61%)
2,021.2 2,150.8 2,411 838.3 2.8 209.7 10.5% analyze ecmascript module module (72%)
2,002.1 2,059.9 19 105374.8 325.6 440.3 10.4% save snapshot persist (5%)
1,404.9 11,545.2 30,872 45.5 0.1 5.4 7.3% process module process module (81%)
1,255.6 3,366.8 27,252 46.1 0.1 5.6 6.5% internal resolving internal resolving (77%)
934.6 1,275.9 6,014 155.4 0.6 32.3 4.8% parse ecmascript parse ecmascript (65%)
850.7 934.7 10,654 79.8 0.4 6.6 4.4% precompute code generation generate merged code (39%)
826.4 5,638.0 4,059 203.6 0.2 109.1 4.3% chunking chunking (46%)
737.1 843.3 7,220 102.1 0.4 112.2 3.8% compute async module info compute async module info (57%)
630.4 2,048.3 1,004 627.9 1.7 234.8 3.3% generate merged code chunking (44%)
625.4 3,518.9 22,081 28.3 0.0 3.2 3.2% resolving module (55%)
417.8 417.8 329 1269.9 1.0 241.1 2.2% generate source map code generation (83%)
338.9 750.6 129 2626.9 4.6 195.6 1.8% emit code generate merged code (41%)
282.9 523.3 1,644 172.1 0.1 145.1 1.5% write all entrypoints to disk write all entrypoints to disk (17%)
221.4 1,053.7 1,959 113.0 0.3 39.5 1.1% code generation code generation (83%)
131.9 289.8 1,686 78.2 0.1 10.1 0.7% compute async chunks compute async chunks (53%)
81.2 103.7 827 98.1 0.1 25.2 0.4% compute binding usage info compute binding usage info (46%)
61.0 61.0 9 6776.9 24.9 27.5 0.3% blocking save snapshot (56%)
60.9 60.9 2,169 28.1 0.0 3.0 0.3% read file parse ecmascript (91%)
47.0 82.7 1,868 25.2 0.0 16.7 0.2% collect mergeable modules collect mergeable modules (99%)

Critical Path Analysis

The longest sequential dependency chains that determine wall-clock time.
Focus on reducing the depth of these chains to improve parallelism.

Rank Self-Time (ms) Depth Path
1 467.8 3 persist → save snapshot → blocking
2 434.1 6 chunking → generate merged code → emit code → emit code → emit code → read file
3 280.0 4 chunking → generate merged code → emit code → generate source map
4 209.8 3 process module → process module → analyze ecmascript module
5 200.6 4 chunking → generate merged code → emit code → generate source map

Batching Candidates

High-volume tasks dominated by a single parent. If the parent can batch them,
it drastically reduces scheduler overhead.

Task Name Count Top Caller (Attribution) Avg Self P95 Self Total Self
process module 30,872 process module (81%) 45.5 us 0.07 ms 1,404.9 ms
internal resolving 27,252 internal resolving (77%) 46.1 us 0.09 ms 1,255.6 ms

Duration Distribution

Range Count Percentage
<10us 600,081 73.2%
10us-100us 144,188 17.6%
100us-1ms 64,428 7.9%
1ms-10ms 10,809 1.3%
10ms-100ms 155 0.0%
>100ms 35 0.0%

Action Items

  1. [P0] Focus on tasks with the highest Self-Time — these are where CPU cycles are actually spent.
  2. [P0] Use Batching Candidates to identify callers that should use try_join or reduce #[turbo_tasks::function] granularity.
  3. [P1] Check Build Phase Timeline for phases with disproportionate wall range vs. self-time (= serialization).
  4. [P1] Inspect P95 Self (ms) for heavy monolith tasks. Focus on long-tail outliers, not averages.
  5. [P1] Review Critical Paths — reducing the longest chain depth directly improves wall-clock time.
  6. [P2] If Thread Utilization < 60%, investigate scheduling gaps (lock contention or deep dependency chains).

Report generated by Utoopack Performance Analysis Agent

@fireairforce
fireairforce enabled auto-merge (squash) September 9, 2026 09:16
@hongxuWei
hongxuWei self-requested a review September 9, 2026 09:18
@fireairforce
fireairforce merged commit 9ec423b into next Sep 9, 2026
81 of 88 checks passed
@fireairforce
fireairforce deleted the zoomdong/short-production-chunk-names branch September 9, 2026 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants