Skip to content

fix(pack): restore lazy imports after persistent cache restarts - #3371

Open
fireairforce wants to merge 2 commits into
nextfrom
zoomdong/fix-lazy-3367
Open

fireairforce wants to merge 2 commits into
nextfrom
zoomdong/fix-lazy-3367

Conversation

@fireairforce

@fireairforce fireairforce commented Sep 18, 2026

Copy link
Copy Markdown
Member

Summary

Fixes #3367.

Update the next.js submodule to 075f9b7829b4fdcbcf80eae337d0ff3f2813cf75 from the merged core fix utooland/next.js#193. The fix recreates lazy compilation dependency subscriptions after restoring the filesystem cache, allowing previously unopened nested imports to activate after a dev-server restart.

The same core fix has also been submitted upstream to Turbopack: vercel/next.js#98867.

Test Plan

  • Confirmed that the merged submodule commit has the same Git tree as the previously validated fix.
  • cargo fmt --check
  • cargo clippy --all-targets -- -D warnings --no-deps
  • cargo build --profile release-local -p pack-napi --features plugin
  • Ran the local [pack] lazyDynamicImports serves an inactive proxy on Ant Design/dumi component pages #3367 reproduction against the rebuilt binding: save a cache with an inactive nested import, restart and activate it, then restart and activate it again. All three phases passed, including checks of the served manifests and referenced chunks.

@fireairforce
fireairforce marked this pull request as ready for review September 18, 2026 09:26
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 18, 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-18T09:29:47.596709Z f4bc9c7 Draft marked ready
ℹ️ 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.

@github-actions

Copy link
Copy Markdown

📊 Performance Benchmark Report (with-antd)

Utoopack Performance Report

Report ID: utoopack_performance_report_20260918_093914
Generated: 2026-09-18 09:39:14
Trace File: trace_antd.json (0.3GB, 0.82M spans)
Test Project: examples/with-antd


Executive Summary

Metric Value Assessment
Total Wall Time 6,130.9 ms Baseline
Total Thread Work (de-duped) 18,310.7 ms Non-overlapping busy time
Effective Parallelism 3.0x thread_work / wall_time
Working Threads 10 Threads with actual spans
Thread Utilization 29.9% ⚠️ Suboptimal
Total Spans 824,200 All B/E + X events
Meaningful Spans (>= 10us) 183,140 (22.2% of total)
Tracing Noise (< 10us) 641,060 (77.8% 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 38,298 4,976.1 1,324.7 2,414.2
Parse 8,136 1,025.8 751.2 5,107.1
Analyze 120,010 32,751.3 7,139.1 5,024.4
Chunk 4,748 5,257.1 885.5 2,308.8
Codegen 9,753 2,226.6 1,460.3 1,902.5
Emit 36 36.5 18.4 9.2
Other 2,159 8,805.8 5,253.9 6,130.9

Workload Distribution by Diagnostic Tier

Category Spans Inclusive (ms) % Work Self-Time (ms) % Self
P0: Scheduling & Resolution 158,435 38,232.6 208.8% 8,697.7 47.5%
P1: I/O & Heavy Tasks 2,735 94.6 0.5% 76.5 0.4%
P2: Architecture (Locks/Memory) 0 0.0 0.0% 0.0 0.0%
P3: Asset Pipeline 21,089 8,562.7 46.8% 3,133.8 17.1%
P4: Bridge/Interop 0 0.0 0.0% 0.0 0.0%
Other 881 8,189.3 44.7% 4,925.2 26.9%

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
3,408.5 3,900.3 18 189359.2 380.2 636.2 18.6% save snapshot persist (6%)
3,395.4 19,356.9 80,541 42.2 0.1 8.4 18.5% module module (60%)
1,682.7 1,791.3 2,170 775.4 2.5 165.1 9.2% analyze ecmascript module module (80%)
1,009.1 10,317.5 29,368 34.4 0.0 4.9 5.5% process module process module (81%)
916.6 1,044.9 5,568 164.6 0.5 209.6 5.0% compute async module info compute async module info (49%)
914.8 996.2 7,688 119.0 0.4 13.0 5.0% precompute code generation generate merged code (49%)
872.6 2,351.8 20,899 41.8 0.1 5.4 4.8% internal resolving internal resolving (72%)
700.4 4,907.8 3,796 184.5 0.1 45.2 3.8% chunking chunking (56%)
699.4 974.0 5,970 117.2 0.4 29.1 3.8% parse ecmascript parse ecmascript (66%)
625.5 2,038.1 603 1037.3 2.4 227.6 3.4% generate merged code chunking (60%)
492.3 492.3 7 70326.7 173.9 189.2 2.7% blocking save snapshot (71%)
445.8 2,618.1 16,866 26.4 0.0 4.2 2.4% resolving module (63%)
378.6 378.6 329 1150.9 0.9 202.4 2.1% generate source map code generation (83%)
356.6 720.8 130 2743.1 5.2 190.3 1.9% emit code emit code (42%)
317.9 549.1 993 320.2 0.2 192.5 1.7% write all entrypoints to disk write all entrypoints to disk (10%)
180.1 343.9 898 200.6 0.4 58.3 1.0% compute async chunks compute async chunks (56%)
166.9 851.8 1,736 96.2 0.2 40.2 0.9% code generation code generation (83%)
88.5 105.1 618 143.2 0.0 30.2 0.5% compute binding usage info compute binding usage info (65%)
51.8 51.8 2,165 23.9 0.0 3.1 0.3% read file parse ecmascript (91%)
34.1 62.4 1,730 19.7 0.0 11.9 0.2% collect mergeable modules collect mergeable modules (100%)

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 825.4 3 persist → save snapshot → blocking
2 420.7 6 chunking → generate merged code → emit code → emit code → emit code → read file
3 308.3 2 save snapshot → blocking
4 251.8 4 chunking → generate merged code → emit code → generate source map
5 165.4 8 module → module → process module → process module → process module → process module → process module → analyze ecmascript module

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 29,368 process module (81%) 34.4 us 0.05 ms 1,009.1 ms
internal resolving 20,899 internal resolving (72%) 41.8 us 0.06 ms 872.6 ms

Duration Distribution

Range Count Percentage
<10us 641,060 77.8%
10us-100us 116,198 14.1%
100us-1ms 58,588 7.1%
1ms-10ms 8,162 1.0%
10ms-100ms 142 0.0%
>100ms 50 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

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.

[pack] lazyDynamicImports serves an inactive proxy on Ant Design/dumi component pages

1 participant