Skip to content

Commit 09bdc45

Browse files
authored
Turbopack: improve incremental build performance when deployment id changes (#84460)
### What? * avoid dependencies due to tracing * Avoid invalidating client chunking context when chunk_suffix_path changes * BrowserChunkingContext::chunk_path only depends on a selected subset of fields * select cross_origin field instead of depending on the whole config * select NextConfig::output field instead of depending on the whole config * make all next config fields private to ensure using selector functions
1 parent f8816b0 commit 09bdc45

File tree

14 files changed

+235
-98
lines changed

14 files changed

+235
-98
lines changed

crates/next-api/src/middleware.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,14 @@ impl MiddlewareEndpoint {
157157
parse_segment_config_from_source(*self.await?.source, ParseSegmentMode::Base).await?;
158158
let runtime = config.runtime.unwrap_or(NextRuntime::Edge);
159159

160-
let next_config = this.project.next_config().await?;
161-
let has_i18n = next_config.i18n.is_some();
162-
let has_i18n_locales = next_config
163-
.i18n
160+
let next_config = this.project.next_config();
161+
let i18n = next_config.i18n().await?;
162+
let has_i18n = i18n.is_some();
163+
let has_i18n_locales = i18n
164164
.as_ref()
165165
.map(|i18n| i18n.locales.len() > 1)
166166
.unwrap_or(false);
167-
let base_path = next_config.base_path.as_ref();
167+
let base_path = next_config.base_path().await?;
168168

169169
let matchers = if let Some(matchers) = config.middleware_matcher.as_ref() {
170170
matchers
@@ -202,7 +202,7 @@ impl MiddlewareEndpoint {
202202

203203
source.insert_str(0, "/:nextData(_next/data/[^/]{1,})?");
204204

205-
if let Some(base_path) = base_path {
205+
if let Some(base_path) = base_path.as_ref() {
206206
source.insert_str(0, base_path);
207207
}
208208

crates/next-api/src/nft_json.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,9 @@ pub async fn all_assets_from_entries_filtered(
408408
Ok((
409409
*asset,
410410
if emit_spans {
411-
Some(asset.path().to_string().await?)
411+
// INVALIDATION: we don't need to invalidate the list of assets when
412+
// the span name changes
413+
Some(asset.path_string().untracked().await?)
412414
} else {
413415
None
414416
},
@@ -498,7 +500,9 @@ async fn get_referenced_server_assets(
498500
Ok(Some((
499501
*asset,
500502
if emit_spans {
501-
Some(asset.path().to_string().await?)
503+
// INVALIDATION: we don't need to invalidate the list of assets when the span
504+
// name changes
505+
Some(asset.path_string().untracked().await?)
502506
} else {
503507
None
504508
},

crates/next-api/src/project.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -479,8 +479,8 @@ impl ProjectContainer {
479479
}
480480

481481
let dist_dir = next_config
482+
.dist_dir()
482483
.await?
483-
.dist_dir
484484
.as_ref()
485485
.map_or_else(|| rcstr!(".next"), |d| d.clone());
486486

@@ -722,13 +722,17 @@ impl Project {
722722

723723
#[turbo_tasks::function]
724724
pub async fn client_relative_path(self: Vc<Self>) -> Result<Vc<FileSystemPath>> {
725-
let next_config = self.next_config().await?;
725+
let next_config = self.next_config();
726726
Ok(self
727727
.client_root()
728728
.await?
729729
.join(&format!(
730730
"{}/_next",
731-
next_config.base_path.clone().unwrap_or_default(),
731+
next_config
732+
.base_path()
733+
.await?
734+
.as_deref()
735+
.unwrap_or_default(),
732736
))?
733737
.cell())
734738
}
@@ -1156,26 +1160,38 @@ impl Project {
11561160
*config.persistent_caching_enabled().await?,
11571161
);
11581162

1159-
let config = &config.await?;
1160-
1161-
emit_event("modularizeImports", config.modularize_imports.is_some());
1162-
emit_event("transpilePackages", config.transpile_packages.is_some());
1163+
emit_event(
1164+
"modularizeImports",
1165+
!config.modularize_imports().await?.is_empty(),
1166+
);
1167+
emit_event(
1168+
"transpilePackages",
1169+
!config.transpile_packages().await?.is_empty(),
1170+
);
11631171
emit_event("turbotrace", false);
11641172

11651173
// compiler options
1166-
let compiler_options = config.compiler.as_ref();
1167-
let swc_relay_enabled = compiler_options.and_then(|c| c.relay.as_ref()).is_some();
1174+
let compiler_options = config.compiler().await?;
1175+
let swc_relay_enabled = compiler_options.relay.is_some();
11681176
let styled_components_enabled = compiler_options
1169-
.and_then(|c| c.styled_components.as_ref().map(|sc| sc.is_enabled()))
1177+
.styled_components
1178+
.as_ref()
1179+
.map(|sc| sc.is_enabled())
11701180
.unwrap_or_default();
11711181
let react_remove_properties_enabled = compiler_options
1172-
.and_then(|c| c.react_remove_properties.as_ref().map(|rc| rc.is_enabled()))
1182+
.react_remove_properties
1183+
.as_ref()
1184+
.map(|rc| rc.is_enabled())
11731185
.unwrap_or_default();
11741186
let remove_console_enabled = compiler_options
1175-
.and_then(|c| c.remove_console.as_ref().map(|rc| rc.is_enabled()))
1187+
.remove_console
1188+
.as_ref()
1189+
.map(|rc| rc.is_enabled())
11761190
.unwrap_or_default();
11771191
let emotion_enabled = compiler_options
1178-
.and_then(|c| c.emotion.as_ref().map(|e| e.is_enabled()))
1192+
.emotion
1193+
.as_ref()
1194+
.map(|e| e.is_enabled())
11791195
.unwrap_or_default();
11801196

11811197
emit_event("swcRelay", swc_relay_enabled);

crates/next-core/src/emit.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use anyhow::Result;
22
use tracing::{Instrument, Level, Span};
33
use turbo_rcstr::RcStr;
44
use turbo_tasks::{
5-
FxIndexSet, ReadRef, ResolvedVc, TryFlatJoinIterExt, TryJoinIterExt, ValueToString, Vc,
5+
FxIndexSet, ReadRef, ResolvedVc, TryFlatJoinIterExt, TryJoinIterExt, Vc,
66
graph::{AdjacencyMap, GraphTraversal, Visit, VisitControlFlow},
77
};
88
use turbo_tasks_fs::{FileSystemPath, rebase};
@@ -161,7 +161,9 @@ pub async fn all_assets_from_entries(entries: Vc<OutputAssets>) -> Result<Vc<Out
161161
Ok((
162162
*asset,
163163
if emit_spans {
164-
Some(asset.path().to_string().await?)
164+
// INVALIDATION: we don't need to invalidate when the span name
165+
// changes
166+
Some(asset.path_string().untracked().await?)
165167
} else {
166168
None
167169
},
@@ -195,7 +197,9 @@ async fn get_referenced_assets(
195197
Ok((
196198
*asset,
197199
if emit_spans {
198-
Some(asset.path().to_string().await?)
200+
// INVALIDATION: we don't need to invalidate the list of assets when the span
201+
// name changes
202+
Some(asset.path_string().untracked().await?)
199203
} else {
200204
None
201205
},

crates/next-core/src/next_app/app_page_entry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub async fn get_app_page_entry(
4848
let server_component_transition =
4949
ResolvedVc::upcast(NextServerComponentTransition::new().to_resolved().await?);
5050

51-
let base_path = next_config.await?.base_path.clone();
51+
let base_path = next_config.base_path().owned().await?;
5252
let loader_tree = AppPageLoaderTreeModule::build(
5353
loader_tree,
5454
module_asset_context,

crates/next-core/src/next_app/app_route_entry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ pub async fn get_app_route_entry(
6060
let inner = rcstr!("INNER_APP_ROUTE");
6161

6262
let output_type: &str = next_config
63+
.output()
6364
.await?
64-
.output
6565
.as_ref()
6666
.map(|o| match o {
6767
OutputType::Standalone => "\"standalone\"",

crates/next-core/src/next_client/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ pub async fn get_client_chunking_context(
447447

448448
let next_mode = mode.await?;
449449
let asset_prefix = asset_prefix.owned().await?;
450-
let chunk_suffix_path = chunk_suffix_path.owned().await?;
450+
let chunk_suffix_path = chunk_suffix_path.to_resolved().await?;
451451
let mut builder = BrowserChunkingContext::builder(
452452
root_path,
453453
client_root.clone(),

crates/next-core/src/next_client_reference/visit_client_reference.rs

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ use std::future::Future;
33
use anyhow::Result;
44
use rustc_hash::FxHashSet;
55
use serde::{Deserialize, Serialize};
6-
use tracing::Instrument;
6+
use tracing::{Instrument, Level, Span};
77
use turbo_rcstr::RcStr;
88
use turbo_tasks::{
9-
FxIndexSet, NonLocalValue, ReadRef, ResolvedVc, TryJoinIterExt, ValueToString, Vc,
9+
FxIndexSet, NonLocalValue, ReadRef, ResolvedVc, TryJoinIterExt, Vc,
1010
debug::ValueDebugFormat,
1111
graph::{AdjacencyMap, GraphTraversal, Visit, VisitControlFlow},
1212
trace::TraceRawVcs,
@@ -121,14 +121,23 @@ pub async fn find_server_entries(
121121
include_traced: bool,
122122
) -> Result<Vc<ServerEntries>> {
123123
async move {
124+
let emit_spans = tracing::enabled!(Level::INFO);
124125
let graph = AdjacencyMap::new()
125126
.skip_duplicates()
126127
.visit(
127128
vec![FindServerEntriesNode::Internal(
128129
entry,
129-
entry.ident().to_string().await?,
130+
if emit_spans {
131+
// INVALIDATION: we don't need to invalidate when the span name changes
132+
Some(entry.ident_string().untracked().await?)
133+
} else {
134+
None
135+
},
130136
)],
131-
FindServerEntries { include_traced },
137+
FindServerEntries {
138+
include_traced,
139+
emit_spans,
140+
},
132141
)
133142
.await
134143
.completed()?
@@ -161,6 +170,7 @@ pub async fn find_server_entries(
161170
struct FindServerEntries {
162171
/// Whether to walk ChunkingType::Traced references
163172
include_traced: bool,
173+
emit_spans: bool,
164174
}
165175

166176
#[derive(
@@ -177,9 +187,12 @@ struct FindServerEntries {
177187
)]
178188
enum FindServerEntriesNode {
179189
ClientReference,
180-
ServerComponentEntry(ResolvedVc<NextServerComponentModule>, ReadRef<RcStr>),
181-
ServerUtilEntry(ResolvedVc<NextServerUtilityModule>, ReadRef<RcStr>),
182-
Internal(ResolvedVc<Box<dyn Module>>, ReadRef<RcStr>),
190+
ServerComponentEntry(
191+
ResolvedVc<NextServerComponentModule>,
192+
Option<ReadRef<RcStr>>,
193+
),
194+
ServerUtilEntry(ResolvedVc<NextServerUtilityModule>, Option<ReadRef<RcStr>>),
195+
Internal(ResolvedVc<Box<dyn Module>>, Option<ReadRef<RcStr>>),
183196
}
184197

185198
impl Visit<FindServerEntriesNode> for FindServerEntries {
@@ -208,6 +221,7 @@ impl Visit<FindServerEntriesNode> for FindServerEntries {
208221
FindServerEntriesNode::ServerUtilEntry(module, _) => Vc::upcast(**module),
209222
FindServerEntriesNode::ServerComponentEntry(module, _) => Vc::upcast(**module),
210223
};
224+
let emit_spans = self.emit_spans;
211225
async move {
212226
// Pass include_traced to reuse the same cached `primary_chunkable_referenced_modules`
213227
// task result, but the traced references will be filtered out again afterwards.
@@ -235,7 +249,13 @@ impl Visit<FindServerEntriesNode> for FindServerEntries {
235249
{
236250
return Ok(FindServerEntriesNode::ServerComponentEntry(
237251
server_component_asset,
238-
server_component_asset.ident().to_string().await?,
252+
if emit_spans {
253+
// INVALIDATION: we don't need to invalidate when the span name
254+
// changes
255+
Some(server_component_asset.ident_string().untracked().await?)
256+
} else {
257+
None
258+
},
239259
));
240260
}
241261

@@ -244,13 +264,24 @@ impl Visit<FindServerEntriesNode> for FindServerEntries {
244264
{
245265
return Ok(FindServerEntriesNode::ServerUtilEntry(
246266
server_util_module,
247-
module.ident().to_string().await?,
267+
if emit_spans {
268+
// INVALIDATION: we don't need to invalidate when the span name
269+
// changes
270+
Some(module.ident_string().untracked().await?)
271+
} else {
272+
None
273+
},
248274
));
249275
}
250276

251277
Ok(FindServerEntriesNode::Internal(
252278
*module,
253-
module.ident().to_string().await?,
279+
if emit_spans {
280+
// INVALIDATION: we don't need to invalidate when the span name changes
281+
Some(module.ident_string().untracked().await?)
282+
} else {
283+
None
284+
},
254285
))
255286
});
256287

@@ -261,18 +292,21 @@ impl Visit<FindServerEntriesNode> for FindServerEntries {
261292
}
262293

263294
fn span(&mut self, node: &FindServerEntriesNode) -> tracing::Span {
295+
if !self.emit_spans {
296+
return Span::current();
297+
}
264298
match node {
265299
FindServerEntriesNode::ClientReference => {
266300
tracing::info_span!("client reference")
267301
}
268302
FindServerEntriesNode::Internal(_, name) => {
269-
tracing::info_span!("module", name = display(name))
303+
tracing::info_span!("module", name = display(name.as_ref().unwrap()))
270304
}
271305
FindServerEntriesNode::ServerUtilEntry(_, name) => {
272-
tracing::info_span!("server util", name = display(name))
306+
tracing::info_span!("server util", name = display(name.as_ref().unwrap()))
273307
}
274308
FindServerEntriesNode::ServerComponentEntry(_, name) => {
275-
tracing::info_span!("layout segment", name = display(name))
309+
tracing::info_span!("layout segment", name = display(name.as_ref().unwrap()))
276310
}
277311
}
278312
}

0 commit comments

Comments
 (0)