Skip to content

Commit 488fc1c

Browse files
authored
clear require cache only when needed (#56198)
### What? clear require cache only when there has been changes Before we cleared the require.cache after every ensurePage call. This is too much. The new approach compares the hashes of all emitted files with the previous hashes and only clears require.cache when they differ. ### Why? reloading a page and client navigation is slow due the re-requiring server files Closes WEB-1686
1 parent 2cf8e6c commit 488fc1c

File tree

12 files changed

+137
-45
lines changed

12 files changed

+137
-45
lines changed

packages/next-swc/crates/napi/src/next_api/endpoint.rs

+23-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use std::ops::Deref;
22

33
use napi::{bindgen_prelude::External, JsFunction};
4-
use next_api::route::{Endpoint, WrittenEndpoint};
4+
use next_api::{
5+
route::{Endpoint, WrittenEndpoint},
6+
server_paths::ServerPath,
7+
};
58
use turbo_tasks::Vc;
69
use turbopack_binding::turbopack::core::error::PrettyPrintError;
710

@@ -14,12 +17,28 @@ use super::utils::{
1417
#[derive(Default)]
1518
pub struct NapiEndpointConfig {}
1619

20+
#[napi(object)]
21+
#[derive(Default)]
22+
pub struct NapiServerPath {
23+
pub path: String,
24+
pub content_hash: String,
25+
}
26+
27+
impl From<&ServerPath> for NapiServerPath {
28+
fn from(server_path: &ServerPath) -> Self {
29+
Self {
30+
path: server_path.path.clone(),
31+
content_hash: format!("{:x}", server_path.content_hash),
32+
}
33+
}
34+
}
35+
1736
#[napi(object)]
1837
#[derive(Default)]
1938
pub struct NapiWrittenEndpoint {
2039
pub r#type: String,
2140
pub entry_path: Option<String>,
22-
pub server_paths: Option<Vec<String>>,
41+
pub server_paths: Option<Vec<NapiServerPath>>,
2342
pub files: Option<Vec<String>>,
2443
pub global_var_name: Option<String>,
2544
pub config: NapiEndpointConfig,
@@ -34,7 +53,7 @@ impl From<&WrittenEndpoint> for NapiWrittenEndpoint {
3453
} => Self {
3554
r#type: "nodejs".to_string(),
3655
entry_path: Some(server_entry_path.clone()),
37-
server_paths: Some(server_paths.clone()),
56+
server_paths: Some(server_paths.iter().map(From::from).collect()),
3857
..Default::default()
3958
},
4059
WrittenEndpoint::Edge {
@@ -44,7 +63,7 @@ impl From<&WrittenEndpoint> for NapiWrittenEndpoint {
4463
} => Self {
4564
r#type: "edge".to_string(),
4665
files: Some(files.clone()),
47-
server_paths: Some(server_paths.clone()),
66+
server_paths: Some(server_paths.iter().map(From::from).collect()),
4867
global_var_name: Some(global_var_name.clone()),
4968
..Default::default()
5069
},

packages/next-swc/crates/next-api/src/app.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use anyhow::{bail, Context, Result};
22
use next_core::{
3-
all_server_paths,
43
app_structure::{
54
get_entrypoints, Entrypoint as AppEntrypoint, Entrypoints as AppEntrypoints, LoaderTree,
65
MetadataItem,
@@ -55,6 +54,7 @@ use turbopack_binding::{
5554
use crate::{
5655
project::Project,
5756
route::{Endpoint, Route, Routes, WrittenEndpoint},
57+
server_paths::all_server_paths,
5858
};
5959

6060
#[turbo_tasks::value]

packages/next-swc/crates/next-api/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod middleware;
88
mod pages;
99
pub mod project;
1010
pub mod route;
11+
pub mod server_paths;
1112
mod versioned_content_map;
1213

1314
// Declare build-time information variables generated in build.rs

packages/next-swc/crates/next-api/src/middleware.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use anyhow::{bail, Context, Result};
22
use next_core::{
3-
all_server_paths,
43
middleware::get_middleware_module,
54
mode::NextMode,
65
next_edge::entry::wrap_edge_entry,
@@ -27,6 +26,7 @@ use turbopack_binding::{
2726
use crate::{
2827
project::Project,
2928
route::{Endpoint, WrittenEndpoint},
29+
server_paths::all_server_paths,
3030
};
3131

3232
#[turbo_tasks::value]

packages/next-swc/crates/next-api/src/pages.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::{bail, Context, Result};
22
use indexmap::IndexMap;
33
use next_core::{
4-
all_server_paths, create_page_loader_entry_module, get_asset_path_from_pathname,
4+
create_page_loader_entry_module, get_asset_path_from_pathname,
55
get_edge_resolve_options_context,
66
mode::NextMode,
77
next_client::{
@@ -64,6 +64,7 @@ use turbopack_binding::{
6464
use crate::{
6565
project::Project,
6666
route::{Endpoint, Route, Routes, WrittenEndpoint},
67+
server_paths::all_server_paths,
6768
};
6869

6970
#[turbo_tasks::value]

packages/next-swc/crates/next-api/src/route.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use indexmap::IndexMap;
22
use turbo_tasks::{Completion, Vc};
33

4+
use crate::server_paths::ServerPath;
5+
46
#[turbo_tasks::value(shared)]
57
#[derive(Copy, Clone, Debug)]
68
pub enum Route {
@@ -34,15 +36,13 @@ pub enum WrittenEndpoint {
3436
NodeJs {
3537
/// Relative to the root_path
3638
server_entry_path: String,
37-
/// Relative to the root_path
38-
server_paths: Vec<String>,
39+
server_paths: Vec<ServerPath>,
3940
},
4041
Edge {
4142
/// Relative to the root_path
4243
files: Vec<String>,
4344
global_var_name: String,
44-
/// Relative to the root_path
45-
server_paths: Vec<String>,
45+
server_paths: Vec<ServerPath>,
4646
},
4747
}
4848

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use anyhow::Result;
2+
use next_core::all_assets_from_entries;
3+
use serde::{Deserialize, Serialize};
4+
use turbo_tasks::{trace::TraceRawVcs, TryFlatJoinIterExt, Vc};
5+
use turbopack_binding::{
6+
turbo::tasks_fs::FileSystemPath,
7+
turbopack::core::{
8+
asset::{Asset, AssetContent},
9+
output::{OutputAsset, OutputAssets},
10+
},
11+
};
12+
13+
/// A reference to a server file with content hash for change detection
14+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, TraceRawVcs)]
15+
pub struct ServerPath {
16+
/// Relative to the root_path
17+
pub path: String,
18+
pub content_hash: u64,
19+
}
20+
21+
/// A list of server paths
22+
#[turbo_tasks::value(transparent)]
23+
pub struct ServerPaths(Vec<ServerPath>);
24+
25+
/// Return a list of all server paths with filename and hash for all output
26+
/// assets references from the `assets` list. Server paths are identified by
27+
/// being inside of `node_root`.
28+
#[turbo_tasks::function]
29+
pub async fn all_server_paths(
30+
assets: Vc<OutputAssets>,
31+
node_root: Vc<FileSystemPath>,
32+
) -> Result<Vc<ServerPaths>> {
33+
let all_assets = all_assets_from_entries(assets).await?;
34+
let node_root = &node_root.await?;
35+
Ok(Vc::cell(
36+
all_assets
37+
.iter()
38+
.map(|&asset| async move {
39+
Ok(
40+
if let Some(path) = node_root.get_path_to(&*asset.ident().path().await?) {
41+
let content_hash = match *asset.content().await? {
42+
AssetContent::File(file) => *file.hash().await?,
43+
AssetContent::Redirect { .. } => 0,
44+
};
45+
Some(ServerPath {
46+
path: path.to_string(),
47+
content_hash,
48+
})
49+
} else {
50+
None
51+
},
52+
)
53+
})
54+
.try_flat_join()
55+
.await?,
56+
))
57+
}

packages/next-swc/crates/next-core/src/emit.rs

+1-24
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,14 @@
11
use anyhow::Result;
22
use turbo_tasks::{
33
graph::{AdjacencyMap, GraphTraversal},
4-
Completion, Completions, TryFlatJoinIterExt, TryJoinIterExt, Vc,
4+
Completion, Completions, TryFlatJoinIterExt, Vc,
55
};
66
use turbo_tasks_fs::{rebase, FileSystemPath};
77
use turbopack_binding::turbopack::core::{
88
asset::Asset,
99
output::{OutputAsset, OutputAssets},
1010
};
1111

12-
#[turbo_tasks::function]
13-
pub async fn all_server_paths(
14-
assets: Vc<OutputAssets>,
15-
node_root: Vc<FileSystemPath>,
16-
) -> Result<Vc<Vec<String>>> {
17-
let all_assets = all_assets_from_entries(assets).await?;
18-
let node_root = &node_root.await?;
19-
Ok(Vc::cell(
20-
all_assets
21-
.iter()
22-
.map(|&asset| async move {
23-
Ok(node_root
24-
.get_path_to(&*asset.ident().path().await?)
25-
.map(|s| s.to_string()))
26-
})
27-
.try_join()
28-
.await?
29-
.into_iter()
30-
.flatten()
31-
.collect(),
32-
))
33-
}
34-
3512
/// Emits all assets transitively reachable from the given chunks, that are
3613
/// inside the node root or the client root.
3714
///

packages/next-swc/crates/next-core/src/lib.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ pub mod util;
4646
pub use app_segment_config::{
4747
parse_segment_config_from_loader_tree, parse_segment_config_from_source,
4848
};
49-
pub use emit::{
50-
all_assets_from_entries, all_server_paths, emit_all_assets, emit_assets, emit_client_assets,
51-
};
49+
pub use emit::{all_assets_from_entries, emit_all_assets, emit_assets, emit_client_assets};
5250
pub use next_edge::context::{
5351
get_edge_chunking_context, get_edge_compile_time_info, get_edge_resolve_options_context,
5452
};

packages/next/src/build/swc/index.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -540,20 +540,25 @@ interface EndpointConfig {
540540
preferredRegion?: string
541541
}
542542

543+
export type ServerPath = {
544+
path: string
545+
contentHash: string
546+
}
547+
543548
export type WrittenEndpoint =
544549
| {
545550
type: 'nodejs'
546551
/** The entry path for the endpoint. */
547552
entryPath: string
548553
/** All server paths that has been written for the endpoint. */
549-
serverPaths: string[]
554+
serverPaths: ServerPath[]
550555
config: EndpointConfig
551556
}
552557
| {
553558
type: 'edge'
554559
files: string[]
555560
/** All server paths that has been written for the endpoint. */
556-
serverPaths: string[]
561+
serverPaths: ServerPath[]
557562
globalVarName: string
558563
config: EndpointConfig
559564
}

0 commit comments

Comments
 (0)