Skip to content

Commit

Permalink
feat: align stats chunk group (#6961)
Browse files Browse the repository at this point in the history
* feat: align stats chunk group

* feat: align stats chunk group

* feat: align stats chunk group

* feat: align stats chunk group
  • Loading branch information
LingyuCoder authored Jun 27, 2024
1 parent f9807a1 commit 8333238
Show file tree
Hide file tree
Showing 16 changed files with 524 additions and 55 deletions.
14 changes: 11 additions & 3 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ export class JsStats {
getAssets(): JsStatsGetAssets
getModules(reasons: boolean, moduleAssets: boolean, nestedModules: boolean, source: boolean, usedExports: boolean, providedExports: boolean): Array<JsStatsModule>
getChunks(chunkModules: boolean, chunksRelations: boolean, reasons: boolean, moduleAssets: boolean, nestedModules: boolean, source: boolean, usedExports: boolean, providedExports: boolean): Array<JsStatsChunk>
getEntrypoints(): Array<JsStatsChunkGroup>
getNamedChunkGroups(): Array<JsStatsChunkGroup>
getEntrypoints(chunkGroupAuxiliary: boolean, chunkGroupChildren: boolean): Array<JsStatsChunkGroup>
getNamedChunkGroups(chunkGroupAuxiliary: boolean, chunkGroupChildren: boolean): Array<JsStatsChunkGroup>
getErrors(): Array<JsStatsError>
getWarnings(): Array<JsStatsWarning>
getLogging(acceptedTypes: number): Array<JsStatsLogging>
Expand Down Expand Up @@ -547,16 +547,24 @@ export interface JsStatsChunk {

export interface JsStatsChunkGroup {
name: string
assets: Array<JsStatsChunkGroupAsset>
chunks: Array<string | undefined | null>
assets: Array<JsStatsChunkGroupAsset>
assetsSize: number
auxiliaryAssets?: Array<JsStatsChunkGroupAsset>
auxiliaryAssetsSize?: number
children?: JsStatsChunkGroupChildren
}

export interface JsStatsChunkGroupAsset {
name: string
size: number
}

export interface JsStatsChunkGroupChildren {
preload?: Array<JsStatsChunkGroup>
prefetch?: Array<JsStatsChunkGroup>
}

export interface JsStatsError {
message: string
moduleIdentifier?: string
Expand Down
45 changes: 39 additions & 6 deletions crates/rspack_binding_values/src/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,18 +563,43 @@ impl From<rspack_core::StatsChunkGroupAsset> for JsStatsChunkGroupAsset {
#[napi(object)]
pub struct JsStatsChunkGroup {
pub name: String,
pub assets: Vec<JsStatsChunkGroupAsset>,
pub chunks: Vec<Option<String>>,
pub assets: Vec<JsStatsChunkGroupAsset>,
pub assets_size: f64,
pub auxiliary_assets: Option<Vec<JsStatsChunkGroupAsset>>,
pub auxiliary_assets_size: Option<f64>,
pub children: Option<JsStatsChunkGroupChildren>,
}

impl From<rspack_core::StatsChunkGroup> for JsStatsChunkGroup {
fn from(stats: rspack_core::StatsChunkGroup) -> Self {
Self {
name: stats.name,
assets: stats.assets.into_iter().map(Into::into).collect(),
chunks: stats.chunks,
assets: stats.assets.into_iter().map(Into::into).collect(),
assets_size: stats.assets_size,
auxiliary_assets: stats
.auxiliary_assets
.map(|assets| assets.into_iter().map(Into::into).collect()),
auxiliary_assets_size: stats.auxiliary_assets_size,
children: stats.children.map(|i| i.into()),
}
}
}

#[napi(object)]
pub struct JsStatsChunkGroupChildren {
pub preload: Option<Vec<JsStatsChunkGroup>>,
pub prefetch: Option<Vec<JsStatsChunkGroup>>,
}

impl From<rspack_core::StatsChunkGroupChildren> for JsStatsChunkGroupChildren {
fn from(stats: rspack_core::StatsChunkGroupChildren) -> Self {
Self {
preload: (!stats.preload.is_empty())
.then(|| stats.preload.into_iter().map(Into::into).collect()),
prefetch: (!stats.prefetch.is_empty())
.then(|| stats.prefetch.into_iter().map(Into::into).collect()),
}
}
}
Expand Down Expand Up @@ -683,20 +708,28 @@ impl JsStats {
}

#[napi]
pub fn get_entrypoints(&self) -> Vec<JsStatsChunkGroup> {
pub fn get_entrypoints(
&self,
chunk_group_auxiliary: bool,
chunk_group_children: bool,
) -> Vec<JsStatsChunkGroup> {
self
.inner
.get_entrypoints()
.get_entrypoints(chunk_group_auxiliary, chunk_group_children)
.into_iter()
.map(Into::into)
.collect()
}

#[napi]
pub fn get_named_chunk_groups(&self) -> Vec<JsStatsChunkGroup> {
pub fn get_named_chunk_groups(
&self,
chunk_group_auxiliary: bool,
chunk_group_children: bool,
) -> Vec<JsStatsChunkGroup> {
self
.inner
.get_named_chunk_groups()
.get_named_chunk_groups(chunk_group_auxiliary, chunk_group_children)
.into_iter()
.map(Into::into)
.collect()
Expand Down
49 changes: 46 additions & 3 deletions crates/rspack_core/src/chunk_group.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use std::cmp::Ordering;
use std::fmt::{self, Display};

use itertools::Itertools;
use rspack_database::DatabaseItem;
use rspack_error::{error, Result};
use rspack_identifier::IdentifierMap;
use rustc_hash::FxHashSet as HashSet;
use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet};

use crate::{
get_chunk_from_ukey, Chunk, ChunkByUkey, ChunkGroupByUkey, ChunkGroupUkey, DependencyLocation,
FilenameTemplate,
compare_chunk_group, get_chunk_from_ukey, get_chunk_group_from_ukey, Chunk, ChunkByUkey,
ChunkGroupByUkey, ChunkGroupUkey, DependencyLocation, FilenameTemplate,
};
use crate::{ChunkLoading, ChunkUkey, Compilation};
use crate::{LibraryOptions, ModuleIdentifier, PublicPath};
Expand Down Expand Up @@ -320,6 +321,48 @@ impl ChunkGroup {
pub fn origins(&self) -> &Vec<OriginRecord> {
&self.origins
}

pub fn get_children_by_orders(
&self,
compilation: &Compilation,
) -> HashMap<ChunkGroupOrderKey, Vec<ChunkGroupUkey>> {
let mut children_by_orders = HashMap::<ChunkGroupOrderKey, Vec<ChunkGroupUkey>>::default();

let orders = vec![ChunkGroupOrderKey::Preload, ChunkGroupOrderKey::Prefetch];

for order_key in orders {
let mut list = vec![];
for child_ukey in &self.children {
let Some(child_group) =
get_chunk_group_from_ukey(child_ukey, &compilation.chunk_group_by_ukey)
else {
continue;
};
if let Some(order) = child_group
.kind
.get_normal_options()
.and_then(|o| match order_key {
ChunkGroupOrderKey::Prefetch => o.prefetch_order,
ChunkGroupOrderKey::Preload => o.preload_order,
})
{
list.push((order, child_group.ukey));
}
}

list.sort_by(|a, b| {
let cmp = b.0.cmp(&a.0);
match cmp {
Ordering::Equal => compare_chunk_group(&a.1, &b.1, compilation),
_ => cmp,
}
});

children_by_orders.insert(order_key, list.iter().map(|i| i.1).collect_vec());
}

children_by_orders
}
}

#[derive(Debug, Clone)]
Expand Down
122 changes: 103 additions & 19 deletions crates/rspack_core/src/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,53 +410,128 @@ impl Stats<'_> {
Ok(f(chunks))
}

fn get_chunk_group(&self, name: &str, ukey: &ChunkGroupUkey) -> StatsChunkGroup {
fn get_chunk_group(
&self,
name: &str,
ukey: &ChunkGroupUkey,
chunk_group_auxiliary: bool,
chunk_group_children: bool,
) -> StatsChunkGroup {
let cg = self.compilation.chunk_group_by_ukey.expect_get(ukey);
let chunks: Vec<Option<String>> = cg
.chunks
.iter()
.map(|c| self.compilation.chunk_by_ukey.expect_get(c))
.map(|c| c.id.clone())
.collect();
let assets = cg.chunks.iter().fold(Vec::new(), |mut acc, c| {
let chunk = self.compilation.chunk_by_ukey.expect_get(c);
for file in &chunk.files {
acc.push(StatsChunkGroupAsset {
name: file.clone(),
size: self
.compilation
.assets()
.get(file)
.unwrap_or_else(|| panic!("Could not find asset by name: {file:?}"))
.get_source()
.map_or(-1f64, |s| s.size() as f64),
let (assets, auxiliary_assets) =
cg.chunks
.iter()
.fold((Vec::new(), Vec::new()), |(mut acc, mut aacc), c| {
let chunk = self.compilation.chunk_by_ukey.expect_get(c);
for file in &chunk.files {
acc.push(StatsChunkGroupAsset {
name: file.clone(),
size: self
.compilation
.assets()
.get(file)
.unwrap_or_else(|| panic!("Could not find asset by name: {file:?}"))
.get_source()
.map_or(-1f64, |s| s.size() as f64),
});
}
if chunk_group_auxiliary {
for file in &chunk.auxiliary_files {
aacc.push(StatsChunkGroupAsset {
name: file.clone(),
size: self
.compilation
.assets()
.get(file)
.unwrap_or_else(|| panic!("Could not find asset by name: {file:?}"))
.get_source()
.map_or(-1f64, |s| s.size() as f64),
});
}
}

(acc, aacc)
});

let children = chunk_group_children.then(|| {
let ordered_children = cg.get_children_by_orders(self.compilation);

StatsChunkGroupChildren {
preload: ordered_children
.get(&ChunkGroupOrderKey::Preload)
.expect("should have preload chunk groups")
.iter()
.map(|ukey| {
let cg = self.compilation.chunk_group_by_ukey.expect_get(ukey);
self.get_chunk_group(
cg.name().unwrap_or_default(),
ukey,
chunk_group_auxiliary,
false,
)
})
.collect_vec(),
prefetch: ordered_children
.get(&ChunkGroupOrderKey::Prefetch)
.expect("should have prefetch chunk groups")
.iter()
.map(|ukey| {
let cg = self.compilation.chunk_group_by_ukey.expect_get(ukey);
self.get_chunk_group(
cg.name().unwrap_or_default(),
ukey,
chunk_group_auxiliary,
false,
)
})
.collect_vec(),
}
acc
});
StatsChunkGroup {
name: name.to_string(),
chunks,
assets_size: assets.iter().map(|i| i.size).sum(),
assets,
auxiliary_assets_size: chunk_group_auxiliary
.then(|| auxiliary_assets.iter().map(|i| i.size).sum()),
auxiliary_assets: chunk_group_auxiliary.then_some(auxiliary_assets),
children,
}
}

pub fn get_entrypoints(&self) -> Vec<StatsChunkGroup> {
pub fn get_entrypoints(
&self,
chunk_group_auxiliary: bool,
chunk_group_children: bool,
) -> Vec<StatsChunkGroup> {
self
.compilation
.entrypoints
.iter()
.map(|(name, ukey)| self.get_chunk_group(name, ukey))
.map(|(name, ukey)| {
self.get_chunk_group(name, ukey, chunk_group_auxiliary, chunk_group_children)
})
.collect()
}

pub fn get_named_chunk_groups(&self) -> Vec<StatsChunkGroup> {
pub fn get_named_chunk_groups(
&self,
chunk_group_auxiliary: bool,
chunk_group_children: bool,
) -> Vec<StatsChunkGroup> {
let mut named_chunk_groups: Vec<StatsChunkGroup> = self
.compilation
.named_chunk_groups
.iter()
.map(|(name, ukey)| self.get_chunk_group(name, ukey))
.map(|(name, ukey)| {
self.get_chunk_group(name, ukey, chunk_group_auxiliary, chunk_group_children)
})
.collect();
named_chunk_groups.sort_by_cached_key(|e| e.name.to_string());
named_chunk_groups
Expand Down Expand Up @@ -1190,9 +1265,18 @@ pub struct StatsChunkGroupAsset {
#[derive(Debug)]
pub struct StatsChunkGroup {
pub name: String,
pub assets: Vec<StatsChunkGroupAsset>,
pub chunks: Vec<Option<String>>,
pub assets: Vec<StatsChunkGroupAsset>,
pub assets_size: f64,
pub auxiliary_assets: Option<Vec<StatsChunkGroupAsset>>,
pub auxiliary_assets_size: Option<f64>,
pub children: Option<StatsChunkGroupChildren>,
}

#[derive(Debug)]
pub struct StatsChunkGroupChildren {
pub preload: Vec<StatsChunkGroup>,
pub prefetch: Vec<StatsChunkGroup>,
}

#[derive(Debug)]
Expand Down
Loading

2 comments on commit 8333238

@rspack-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Ran ecosystem CI: Open

suite result
modernjs ❌ failure
_selftest ✅ success
nx ✅ success
rspress ❌ failure
rsbuild ❌ failure
compat ❌ failure
examples ❌ failure

@rspack-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Benchmark detail: Open

Name Base (2024-06-26 6b57dd8) Current Change
10000_development-mode + exec 2.26 s ± 27 ms 2.26 s ± 17 ms +0.22 %
10000_development-mode_hmr + exec 744 ms ± 14 ms 737 ms ± 17 ms -0.98 %
10000_production-mode + exec 2.81 s ± 19 ms 3.14 s ± 31 ms +11.76 %
arco-pro_development-mode + exec 1.92 s ± 104 ms 1.96 s ± 84 ms +2.30 %
arco-pro_development-mode_hmr + exec 442 ms ± 2 ms 442 ms ± 1.2 ms -0.05 %
arco-pro_production-mode + exec 3.48 s ± 93 ms 4.07 s ± 79 ms +17.12 %
threejs_development-mode_10x + exec 1.61 s ± 17 ms 1.61 s ± 13 ms +0.01 %
threejs_development-mode_10x_hmr + exec 810 ms ± 6 ms 811 ms ± 7.6 ms +0.12 %
threejs_production-mode_10x + exec 4.91 s ± 33 ms 5.97 s ± 26 ms +21.79 %

Threshold exceeded: ["10000_production-mode + exec","arco-pro_production-mode + exec","threejs_production-mode_10x + exec"]

Please sign in to comment.