Skip to content

Commit 65397a5

Browse files
authored
perf: improve bundle splitting (#11465)
* perf: improve bundle splitting * perf: improve bundle splitting * perf: improve bundle splitting
1 parent 7fd6d64 commit 65397a5

File tree

4 files changed

+41
-49
lines changed

4 files changed

+41
-49
lines changed

crates/rspack_plugin_split_chunks/src/module_group.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ use crate::{
1919
/// The original name of `ModuleGroup` is `ChunkInfoItem` borrowed from Webpack
2020
#[derive(Debug)]
2121
pub(crate) struct ModuleGroup {
22-
/// the real index used for mapping the ModuleGroup to corresponding CacheGroup
23-
idx: CacheGroupIdx,
2422
pub modules: IdentifierSet,
23+
/// the real index used for mapping the ModuleGroup to corresponding CacheGroup
2524
pub cache_group_index: usize,
2625
pub cache_group_priority: f64,
2726
pub cache_group_reuse_existing_chunk: bool,
@@ -37,13 +36,11 @@ pub(crate) struct ModuleGroup {
3736

3837
impl ModuleGroup {
3938
pub fn new(
40-
idx: CacheGroupIdx,
4139
chunk_name: Option<String>,
4240
cache_group_index: usize,
4341
cache_group: &CacheGroup,
4442
) -> Self {
4543
Self {
46-
idx,
4744
modules: Default::default(),
4845
cache_group_index,
4946
cache_group_priority: cache_group.priority,
@@ -116,20 +113,14 @@ impl ModuleGroup {
116113
}
117114

118115
pub fn get_cache_group<'a>(&self, cache_groups: &'a [CacheGroup]) -> &'a CacheGroup {
119-
&cache_groups[self.idx.0]
116+
&cache_groups[self.cache_group_index]
120117
}
121118
}
122119

123-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
124-
pub(crate) struct CacheGroupIdx(usize);
125-
126-
impl CacheGroupIdx {
127-
pub fn new(idx: usize) -> Self {
128-
Self(idx)
129-
}
130-
}
131-
132-
pub(crate) fn compare_entries(a: &ModuleGroup, b: &ModuleGroup) -> f64 {
120+
pub(crate) fn compare_entries(
121+
(a_key, a): (&String, &ModuleGroup),
122+
(b_key, b): (&String, &ModuleGroup),
123+
) -> f64 {
133124
// 1. by priority
134125
let diff_priority = a.cache_group_priority - b.cache_group_priority;
135126
if diff_priority != 0f64 {
@@ -170,7 +161,7 @@ pub(crate) fn compare_entries(a: &ModuleGroup, b: &ModuleGroup) -> f64 {
170161

171162
loop {
172163
match (modules_a.pop(), modules_b.pop()) {
173-
(None, None) => return 0f64,
164+
(None, None) => break,
174165
(Some(a), Some(b)) => {
175166
let res = a.cmp(b);
176167
if !res.is_eq() {
@@ -180,6 +171,8 @@ pub(crate) fn compare_entries(a: &ModuleGroup, b: &ModuleGroup) -> f64 {
180171
_ => unreachable!(),
181172
}
182173
}
174+
175+
a_key.cmp(b_key) as i32 as f64
183176
}
184177

185178
fn total_size(sizes: &SplitChunkSizes) -> f64 {

crates/rspack_plugin_split_chunks/src/plugin/module_group.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ use rspack_core::{
1414
};
1515
use rspack_error::{Result, ToStringResultToRspackResultExt};
1616
use rspack_util::{fx_hash::FxDashMap, tracing_preset::TRACING_BENCH_TARGET};
17-
use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
17+
use rustc_hash::{FxHashMap, FxHasher};
1818
use tracing::instrument;
1919

2020
use super::ModuleGroupMap;
2121
use crate::{
2222
SplitChunksPlugin,
2323
common::{ModuleChunks, ModuleSizes},
24-
module_group::{CacheGroupIdx, ModuleGroup, compare_entries},
24+
module_group::{ModuleGroup, compare_entries},
2525
options::{
2626
cache_group::CacheGroup,
2727
cache_group_test::{CacheGroupTest, CacheGroupTestFnCtx},
@@ -34,7 +34,6 @@ type ChunksKey = u64;
3434
/// If a module meets requirements of a `ModuleGroup`. We consider the `Module` and the `CacheGroup`
3535
/// to be a `MatchedItem`, which are consumed later to calculate `ModuleGroup`.
3636
struct MatchedItem<'a> {
37-
idx: CacheGroupIdx,
3837
module: &'a dyn Module,
3938
cache_group_index: usize,
4039
cache_group: &'a CacheGroup,
@@ -303,7 +302,7 @@ impl SplitChunksPlugin {
303302
let best_entry_key = module_group_map
304303
.iter()
305304
.min_by(|a, b| {
306-
if compare_entries(a.1, b.1) < 0f64 {
305+
if compare_entries(*a, *b) < 0f64 {
307306
Ordering::Greater
308307
} else {
309308
Ordering::Less
@@ -359,9 +358,7 @@ impl SplitChunksPlugin {
359358
let module = module_graph.module_by_identifier(module).expect("should have module").as_ref();
360359
let mut temp = Vec::with_capacity(plugin.cache_groups.len());
361360

362-
for idx in 0..plugin.cache_groups.len() {
363-
let cache_group = &plugin.cache_groups[idx];
364-
361+
for cache_group in plugin.cache_groups.iter() {
365362
let mut is_match = true;
366363
// Filter by `splitChunks.cacheGroups.{cacheGroup}.type`
367364
is_match &= (cache_group.r#type)(module);
@@ -385,17 +382,27 @@ impl SplitChunksPlugin {
385382
}
386383
let mut chunk_key_to_string = HashMap::<ChunksKey, String, ChunksKeyHashBuilder>::default();
387384

388-
let filtered = plugin
385+
let mut filtered = plugin
389386
.cache_groups
390387
.iter()
391388
.enumerate()
392-
.filter(|(index, _)| temp[*index]);
389+
.filter(|(index, _)| temp[*index]).collect::<Vec<_>>();
390+
391+
filtered.sort_by(|a, b| {
392+
b.1.priority.partial_cmp(&a.1.priority).unwrap_or_else(|| {
393+
a.0.cmp(&b.0)
394+
})
395+
});
393396

394397
let mut used_exports_combs = None;
395398
let mut non_used_exports_combs = None;
396-
let mut added_keys = FxHashSet::default();
399+
let mut matched_max_priority = None;
400+
401+
for (cache_group_index, cache_group) in filtered.into_iter() {
402+
if let Some(matched_max_priority) = matched_max_priority && cache_group.priority < matched_max_priority {
403+
break;
404+
}
397405

398-
for (cache_group_index, (idx, cache_group)) in filtered.enumerate() {
399406
let combs = if cache_group.used_exports {
400407
if used_exports_combs.is_none() {
401408
used_exports_combs = Some(combinator.get_combs(
@@ -473,9 +480,12 @@ impl SplitChunksPlugin {
473480
let selected_chunks_key =
474481
get_key(selected_chunks.iter().copied());
475482

483+
if matched_max_priority.is_none() {
484+
matched_max_priority = Some(cache_group.priority);
485+
}
486+
476487
merge_matched_item_into_module_group_map(
477488
MatchedItem {
478-
idx: CacheGroupIdx::new(idx),
479489
module,
480490
cache_group,
481491
cache_group_index,
@@ -486,7 +496,6 @@ impl SplitChunksPlugin {
486496
&mut chunk_key_to_string,
487497
compilation,
488498
module_sizes,
489-
&mut added_keys,
490499
).await?;
491500
}
492501
}
@@ -598,10 +607,8 @@ async fn merge_matched_item_into_module_group_map(
598607
chunk_key_to_string: &mut HashMap<ChunksKey, String, ChunksKeyHashBuilder>,
599608
compilation: &Compilation,
600609
module_sizes: &ModuleSizes,
601-
added_keys: &mut FxHashSet<String>,
602610
) -> Result<()> {
603611
let MatchedItem {
604-
idx,
605612
module,
606613
cache_group_index,
607614
cache_group,
@@ -647,11 +654,9 @@ async fn merge_matched_item_into_module_group_map(
647654
let mut module_group = {
648655
module_group_map
649656
.entry(key.clone())
650-
.or_insert_with(|| ModuleGroup::new(idx, chunk_name.clone(), cache_group_index, cache_group))
657+
.or_insert_with(|| ModuleGroup::new(chunk_name, cache_group_index, cache_group))
651658
};
652-
if chunk_name.is_none() || added_keys.insert(key) {
653-
module_group.add_module(module.identifier(), module_sizes);
654-
}
659+
module_group.add_module(module.identifier(), module_sizes);
655660
module_group.chunks.extend(selected_chunks.iter().copied());
656661

657662
Ok(())

tests/e2e/cases/css/chunk-loading-order/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import { test, expect } from "@/fixtures";
22

33
test("should be red", async ({ page }) => {
44
await expect(page.locator("#status")).toHaveText("ok");
5-
await expect(page.locator("body")).toHaveCSS("color", "rgb(255, 0, 0)");
5+
await expect(page.locator("body")).toHaveCSS("color", "rgb(0, 0, 255)");
66
});

tests/webpack-test/__snapshots__/StatsTestCases.basictest.js.snap

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2521,20 +2521,22 @@ custom-chunks-filter:
25212521
25222522
custom-chunks-filter-in-cache-groups:
25232523
Entrypoint main xx KiB = custom-xxx.js
2524-
Entrypoint a xx KiB = custom-xxx.js xx KiB
2524+
Entrypoint a xx KiB = custom-xxx.js
25252525
Entrypoint b xx KiB = custom-xxx.js xx KiB
25262526
Entrypoint c xx KiB = custom-xxx.js xx KiB
2527-
chunk (runtime: a, main) custom-xxx.js (async-g) xx bytes <{341}> <{545}> <{70}> <{724}> [rendered]
2527+
chunk (runtime: a, main) custom-xxx.js (async-g) xx bytes <{341}> <{545}> <{724}> [rendered]
25282528
> ./g ./a.js 6:0-47
25292529
dependent modules xx bytes [dependent] 1 module
25302530
./g.js xx bytes [built] [code generated]
2531-
chunk (runtime: a) custom-xxx.js (a) xx bytes (javascript) xx KiB (runtime) ={70}= >{138}< [entry] [rendered]
2531+
chunk (runtime: a) custom-xxx.js (a) xx bytes (javascript) xx KiB (runtime) >{138}< [entry] [rendered]
25322532
> ./a a
25332533
> x a
25342534
> y a
25352535
> z a
2536-
dependent modules xx bytes [dependent] 1 module
2537-
./a.js + 1 modules xx bytes [code generated]
2536+
dependent modules xx bytes [dependent] 3 modules
2537+
cacheable modules xx bytes
2538+
./a.js + 1 modules xx bytes [code generated]
2539+
./node_modules/z.js xx bytes [built] [code generated]
25382540
chunk (runtime: b) custom-xxx.js (b) xx bytes (javascript) xx KiB (runtime) ={545}= [entry] [rendered]
25392541
> ./b b
25402542
> x b
@@ -2557,14 +2559,6 @@ custom-chunks-filter-in-cache-groups:
25572559
./node_modules/x.js xx bytes [built] [code generated]
25582560
./node_modules/y.js xx bytes [built] [code generated]
25592561
./node_modules/z.js xx bytes [built] [code generated]
2560-
chunk (runtime: a) custom-xxx.js (id hint: vendors) xx bytes ={341}= >{138}< [initial] [rendered] split chunk (cache group: defaultVendors)
2561-
> ./a a
2562-
> x a
2563-
> y a
2564-
> z a
2565-
./node_modules/x.js xx bytes [built] [code generated]
2566-
./node_modules/y.js xx bytes [built] [code generated]
2567-
./node_modules/z.js xx bytes [built] [code generated]
25682562
chunk (runtime: main) custom-xxx.js (async-b) xx bytes <{889}> ={545}= [rendered]
25692563
> ./b ./index.js 2:0-47
25702564
dependent modules xx bytes [dependent] 2 modules

0 commit comments

Comments
 (0)