Skip to content

Revert "Turbopack: layout segment optimization for Pages" #77339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 45 additions & 144 deletions crates/next-api/src/pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use tracing::Instrument;
use turbo_rcstr::RcStr;
use turbo_tasks::{
fxindexmap, trace::TraceRawVcs, Completion, FxIndexMap, NonLocalValue, ResolvedVc, TaskInput,
Value, ValueToString, Vc,
Value, Vc,
};
use turbo_tasks_fs::{
self, File, FileContent, FileSystem, FileSystemPath, FileSystemPathOption, VirtualFileSystem,
Expand All @@ -46,15 +46,15 @@ use turbopack_core::{
asset::AssetContent,
chunk::{
availability_info::AvailabilityInfo, ChunkGroupResult, ChunkingContext, ChunkingContextExt,
EvaluatableAsset, EvaluatableAssets,
EntryChunkGroupResult, EvaluatableAsset, EvaluatableAssets,
},
context::AssetContext,
file_source::FileSource,
ident::AssetIdent,
module::Module,
module_graph::{
chunk_group_info::{ChunkGroup, ChunkGroupEntry},
GraphEntries, ModuleGraph, SingleModuleGraph, VisitedModules,
GraphEntries, ModuleGraph,
},
output::{OptionOutputAsset, OutputAsset, OutputAssets},
reference_type::{EcmaScriptModulesReferenceSubType, EntryReferenceSubType, ReferenceType},
Expand Down Expand Up @@ -772,45 +772,7 @@ impl PageEndpoint {
let this = self.await?;
let project = this.pages_project.project();
let evaluatable_assets = self.client_evaluatable_assets();
Ok(project.module_graph_for_modules(evaluatable_assets))
}

#[turbo_tasks::function]
async fn ssr_module_graph(self: Vc<Self>) -> Result<Vc<ModuleGraph>> {
let this = self.await?;
let project = this.pages_project.project();

if *project.per_page_module_graph().await? {
let ssr_chunk_module = self.internal_ssr_chunk_module().await?;
// Implements layout segment optimization to compute a graph "chain" for document, app,
// page
let mut graphs = vec![];
let mut visited_modules = VisitedModules::empty();
for module in [
ssr_chunk_module.document_module,
ssr_chunk_module.app_module,
]
.into_iter()
.flatten()
{
let graph = SingleModuleGraph::new_with_entries_visited_intern(
vec![ChunkGroupEntry::Shared(module)],
visited_modules,
);
graphs.push(graph);
visited_modules = visited_modules.concatenate(graph);
}

let graph = SingleModuleGraph::new_with_entries_visited_intern(
vec![ChunkGroupEntry::Entry(vec![ssr_chunk_module.ssr_module])],
visited_modules,
);
graphs.push(graph);

Ok(ModuleGraph::from_graphs(graphs))
} else {
Ok(*project.whole_app_module_graphs().await?.full)
}
Ok(project.module_graph_for_entries(evaluatable_assets))
}

#[turbo_tasks::function]
Expand Down Expand Up @@ -890,8 +852,10 @@ impl PageEndpoint {
.module();

let config = parse_config_from_source(ssr_module, NextRuntime::default()).await?;
Ok(if config.runtime == NextRuntime::Edge {
let modules = create_page_ssr_entry_module(
let is_edge = matches!(config.runtime, NextRuntime::Edge);

let ssr_module = if is_edge {
create_page_ssr_entry_module(
*this.pathname,
reference_type,
project_root,
Expand All @@ -902,28 +866,15 @@ impl PageEndpoint {
config.runtime,
this.pages_project.project().next_config(),
)
.await?;

InternalSsrChunkModule {
ssr_module: modules.ssr_module,
app_module: modules.app_module,
document_module: modules.document_module,
runtime: config.runtime,
}
} else {
let pathname = &**this.pathname.await?;

// `/_app` and `/_document` never get rendered directly so they don't need to be
// wrapped in the route module.
if pathname == "/_app" || pathname == "/_document" {
InternalSsrChunkModule {
ssr_module: ssr_module.to_resolved().await?,
app_module: None,
document_module: None,
runtime: config.runtime,
}
ssr_module
} else {
let modules = create_page_ssr_entry_module(
create_page_ssr_entry_module(
*this.pathname,
reference_type,
project_root,
Expand All @@ -934,14 +885,12 @@ impl PageEndpoint {
config.runtime,
this.pages_project.project().next_config(),
)
.await?;
InternalSsrChunkModule {
ssr_module: modules.ssr_module,
app_module: modules.app_module,
document_module: modules.document_module,
runtime: config.runtime,
}
}
};

Ok(InternalSsrChunkModule {
ssr_module: ssr_module.to_resolved().await?,
runtime: config.runtime,
}
.cell())
}
Expand All @@ -951,7 +900,7 @@ impl PageEndpoint {
self: Vc<Self>,
ty: SsrChunkType,
node_path: Vc<FileSystemPath>,
node_chunking_context: Vc<NodeJsChunkingContext>,
chunking_context: Vc<NodeJsChunkingContext>,
edge_chunking_context: Vc<Box<dyn ChunkingContext>>,
runtime_entries: Vc<EvaluatableAssets>,
edge_runtime_entries: Vc<EvaluatableAssets>,
Expand All @@ -961,16 +910,14 @@ impl PageEndpoint {

let InternalSsrChunkModule {
ssr_module,
app_module,
document_module,
runtime,
} = *self.internal_ssr_chunk_module().await?;

let project = this.pages_project.project();
// The SSR and Client Graphs are not connected in Pages Router.
// We are only interested in get_next_dynamic_imports_for_endpoint at the
// moment, which only needs the client graph anyway.
let ssr_module_graph = self.ssr_module_graph();
let module_graph = project.module_graph(*ssr_module);

let next_dynamic_imports = if let PageEndpointType::Html = this.ty {
let client_availability_info = self.client_chunks().await?.availability_info;
Expand Down Expand Up @@ -1005,40 +952,6 @@ impl PageEndpoint {
DynamicImportedChunks::default().resolved_cell()
};

let chunking_context: Vc<Box<dyn ChunkingContext>> = match runtime {
NextRuntime::NodeJs => Vc::upcast(node_chunking_context),
NextRuntime::Edge => Vc::upcast(edge_chunking_context),
};

let mut current_chunks = OutputAssets::empty();
let mut current_availability_info = AvailabilityInfo::Root;
for layout in [document_module, app_module].iter().flatten().copied() {
let span = tracing::trace_span!(
"layout segment",
name = display(layout.ident().to_string().await?)
);
async {
let chunk_group = chunking_context
.chunk_group(
layout.ident(),
ChunkGroup::Shared(layout),
ssr_module_graph,
Value::new(current_availability_info),
)
.await?;

current_chunks = current_chunks
.concatenate(*chunk_group.assets)
.resolve()
.await?;
current_availability_info = chunk_group.availability_info;

anyhow::Ok(())
}
.instrument(span)
.await?;
}

let ssr_module_evaluatable = ResolvedVc::try_sidecast(ssr_module)
.context("could not process page loader entry module")?;
let is_edge = matches!(runtime, NextRuntime::Edge);
Expand All @@ -1049,15 +962,18 @@ impl PageEndpoint {
.map(|m| ResolvedVc::upcast(*m))
.chain(std::iter::once(ResolvedVc::upcast(ssr_module_evaluatable)));

let edge_files = edge_chunking_context.evaluated_chunk_group_assets(
ssr_module.ident(),
ChunkGroup::Entry(evaluatable_assets.collect()),
ssr_module_graph,
Value::new(current_availability_info),
);
let edge_files = edge_chunking_context
.evaluated_chunk_group_assets(
ssr_module.ident(),
ChunkGroup::Entry(evaluatable_assets.collect()),
module_graph,
Value::new(AvailabilityInfo::Root),
)
.to_resolved()
.await?;

Ok(SsrChunk::Edge {
files: current_chunks.concatenate(edge_files).to_resolved().await?,
files: edge_files,
dynamic_import_entries,
}
.cell())
Expand All @@ -1068,15 +984,17 @@ impl PageEndpoint {

let ssr_entry_chunk_path_string: RcStr = format!("pages{asset_path}").into();
let ssr_entry_chunk_path = node_path.join(ssr_entry_chunk_path_string);
let ssr_entry_chunk = node_chunking_context
.entry_chunk_group_asset(
let EntryChunkGroupResult {
asset: ssr_entry_chunk,
..
} = *chunking_context
.entry_chunk_group(
ssr_entry_chunk_path,
runtime_entries.with_entry(*ssr_module_evaluatable),
ssr_module_graph,
current_chunks,
Value::new(current_availability_info),
module_graph,
OutputAssets::empty(),
Value::new(AvailabilityInfo::Root),
)
.to_resolved()
.await?;

let server_asset_trace_file = if this
Expand Down Expand Up @@ -1446,8 +1364,6 @@ impl PageEndpoint {
#[turbo_tasks::value]
pub struct InternalSsrChunkModule {
pub ssr_module: ResolvedVc<Box<dyn Module>>,
pub app_module: Option<ResolvedVc<Box<dyn Module>>>,
pub document_module: Option<ResolvedVc<Box<dyn Module>>>,
pub runtime: NextRuntime,
}

Expand Down Expand Up @@ -1551,32 +1467,17 @@ impl Endpoint for PageEndpoint {
let this = self.await?;

let ssr_chunk_module = self.internal_ssr_chunk_module().await?;
let mut modules = vec![ChunkGroupEntry::Entry(vec![ssr_chunk_module.ssr_module])];

let shared_entries = [
ssr_chunk_module.document_module,
ssr_chunk_module.app_module,
];

let modules = shared_entries
.into_iter()
.flatten()
.map(ChunkGroupEntry::Shared)
.chain(std::iter::once(ChunkGroupEntry::Entry(vec![
ssr_chunk_module.ssr_module,
])))
.chain(if this.ty == PageEndpointType::Html {
Some(ChunkGroupEntry::Entry(
self.client_evaluatable_assets()
.await?
.iter()
.map(|m| ResolvedVc::upcast(*m))
.collect(),
))
.into_iter()
} else {
None.into_iter()
})
.collect::<Vec<_>>();
if let PageEndpointType::Html = this.ty {
modules.push(ChunkGroupEntry::Entry(
self.client_evaluatable_assets()
.await?
.iter()
.map(|m| ResolvedVc::upcast(*m))
.collect(),
));
}

Ok(Vc::cell(modules))
}
Expand Down
14 changes: 1 addition & 13 deletions crates/next-api/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,7 @@ impl Project {
}

#[turbo_tasks::function]
pub async fn module_graph_for_modules(
pub async fn module_graph_for_entries(
self: Vc<Self>,
evaluatable_assets: Vc<EvaluatableAssets>,
) -> Result<Vc<ModuleGraph>> {
Expand All @@ -912,18 +912,6 @@ impl Project {
})
}

#[turbo_tasks::function]
pub async fn module_graph_for_entries(
self: Vc<Self>,
entries: Vc<GraphEntries>,
) -> Result<Vc<ModuleGraph>> {
Ok(if *self.per_page_module_graph().await? {
ModuleGraph::from_modules(entries)
} else {
*self.whole_app_module_graphs().await?.full
})
}

#[turbo_tasks::function]
pub async fn whole_app_module_graphs(self: ResolvedVc<Self>) -> Result<Vc<ModuleGraphs>> {
async move {
Expand Down
Loading
Loading