Skip to content

Commit cfbe18c

Browse files
committed
perf: improve bundle splitting
1 parent fbd7c21 commit cfbe18c

File tree

4 files changed

+72
-85
lines changed

4 files changed

+72
-85
lines changed

crates/rspack_core/src/chunk_graph/chunk_graph_chunk.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,39 @@ impl ChunkGraph {
353353
}
354354
}
355355

356+
pub fn disconnect_chunks_and_modules(
357+
&mut self,
358+
chunks: &[ChunkUkey],
359+
modules: &[ModuleIdentifier],
360+
) {
361+
for chunk in chunks.iter() {
362+
let cgc = self.expect_chunk_graph_chunk_mut(*chunk);
363+
for module in modules.iter() {
364+
cgc.modules.remove(module);
365+
if let Some(source_types_by_module) = &mut cgc.source_types_by_module {
366+
source_types_by_module.remove(module);
367+
}
368+
}
369+
}
370+
for module in modules.iter() {
371+
let cgm = self.expect_chunk_graph_module_mut(*module);
372+
for chunk in chunks.iter() {
373+
cgm.chunks.remove(chunk);
374+
}
375+
}
376+
}
377+
378+
pub fn connect_chunk_and_modules(&mut self, chunk: ChunkUkey, modules: &[ModuleIdentifier]) {
379+
for module in modules.iter() {
380+
let cgm = self.expect_chunk_graph_module_mut(*module);
381+
cgm.chunks.insert(chunk);
382+
}
383+
let cgc = self.expect_chunk_graph_chunk_mut(chunk);
384+
for module in modules.iter() {
385+
cgc.modules.insert(*module);
386+
}
387+
}
388+
356389
pub fn get_chunk_modules<'module>(
357390
&self,
358391
chunk: &ChunkUkey,

crates/rspack_plugin_split_chunks/src/plugin/chunk.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -164,29 +164,31 @@ impl SplitChunksPlugin {
164164
original_chunks: &UkeySet<ChunkUkey>,
165165
compilation: &mut Compilation,
166166
) {
167-
for module_identifier in &item.modules {
168-
if let Some(module) = compilation.module_by_identifier(module_identifier)
169-
&& module
170-
.chunk_condition(&new_chunk, compilation)
171-
.is_some_and(|condition| !condition)
172-
{
173-
continue;
174-
}
167+
let modules = item
168+
.modules
169+
.iter()
170+
.filter(|mid| {
171+
if let Some(module) = compilation.module_by_identifier(mid)
172+
&& module
173+
.chunk_condition(&new_chunk, compilation)
174+
.is_some_and(|condition| !condition)
175+
{
176+
return false;
177+
}
178+
true
179+
})
180+
.copied()
181+
.collect::<Vec<_>>();
175182

176-
// First, we remove modules from old chunks
183+
let chunks = original_chunks.iter().copied().collect::<Vec<_>>();
177184

178-
// Remove module from old chunks
179-
for used_chunk in original_chunks {
180-
compilation
181-
.chunk_graph
182-
.disconnect_chunk_and_module(used_chunk, *module_identifier);
183-
}
185+
compilation
186+
.chunk_graph
187+
.disconnect_chunks_and_modules(&chunks, &modules);
184188

185-
// Add module to new chunk
186-
compilation
187-
.chunk_graph
188-
.connect_chunk_and_module(new_chunk, *module_identifier);
189-
}
189+
compilation
190+
.chunk_graph
191+
.connect_chunk_and_modules(new_chunk, &modules);
190192
}
191193

192194
/// Since the modules are moved into the `new_chunk`, we should

crates/rspack_plugin_split_chunks/src/plugin/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ mod max_size;
44
mod min_size;
55
mod module_group;
66

7-
use std::{borrow::Cow, fmt::Debug};
7+
use std::{borrow::Cow, collections::BinaryHeap, fmt::Debug};
88

99
use rspack_collections::UkeyMap;
1010
use rspack_core::{ChunkUkey, Compilation, CompilationOptimizeChunks, Logger, Plugin};

crates/rspack_plugin_split_chunks/src/plugin/module_group.rs

Lines changed: 16 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -488,10 +488,22 @@ impl SplitChunksPlugin {
488488
.intersection(used_chunks)
489489
.next()?;
490490

491-
current_module_group.modules.iter().for_each(|module| {
492-
tracing::trace!("remove module({module}) from {key}");
493-
other_module_group.remove_module(*module, module_sizes);
494-
});
491+
let module_count = other_module_group.modules.len();
492+
493+
let duplicated_modules = if other_module_group.modules.len() > current_module_group.modules.len() {
494+
current_module_group.modules.intersection(&other_module_group.modules).copied().collect::<Vec<_>>()
495+
} else {
496+
other_module_group.modules.intersection(&current_module_group.modules).copied().collect::<Vec<_>>()
497+
};
498+
499+
for module in duplicated_modules {
500+
other_module_group.remove_module(module, module_sizes);
501+
}
502+
503+
if module_count == other_module_group.modules.len() {
504+
// nothing is removed
505+
return None;
506+
}
495507

496508
if other_module_group.modules.is_empty() {
497509
tracing::trace!(
@@ -543,66 +555,6 @@ impl SplitChunksPlugin {
543555
module_group_map.remove(&key);
544556
});
545557
}
546-
547-
// #[allow(clippy::type_complexity)]
548-
// fn prepare_combination_maps(
549-
// module_graph: &ModuleGraph,
550-
// chunk_graph: &ChunkGraph,
551-
// used_exports: bool,
552-
// chunk_by_ukey: &ChunkByUkey,
553-
// ) -> (
554-
// HashMap<ChunksKey, UkeySet<ChunkUkey>, ChunksKeyHashBuilder>,
555-
// FxHashMap<usize, Vec<UkeySet<ChunkUkey>>>,
556-
// Option<FxHashMap<ModuleIdentifier, Vec<UkeySet<ChunkUkey>>>>,
557-
// ) {
558-
// let mut chunk_sets_in_graph =
559-
// HashMap::<ChunksKey, UkeySet<ChunkUkey>, ChunksKeyHashBuilder>::default();
560-
// let mut chunk_sets_by_count = FxHashMap::<usize, Vec<UkeySet<ChunkUkey>>>::default();
561-
562-
// let mut grouped_by_exports_map: Option<FxHashMap<ModuleIdentifier, Vec<UkeySet<ChunkUkey>>>> =
563-
// None;
564-
565-
// if used_exports {
566-
// let mut grouped_by_exports: FxHashMap<ModuleIdentifier, Vec<UkeySet<ChunkUkey>>> =
567-
// Default::default();
568-
// for module in module_graph.modules().keys() {
569-
// let grouped_chunks = Self::group_chunks_by_exports(
570-
// module,
571-
// chunk_graph.get_module_chunks(*module).iter().cloned(),
572-
// module_graph,
573-
// chunk_by_ukey,
574-
// );
575-
// for chunks in &grouped_chunks {
576-
// let chunk_key = get_key(chunks.iter());
577-
// chunk_sets_in_graph.insert(chunk_key, chunks.clone());
578-
// }
579-
580-
// grouped_by_exports.insert(*module, grouped_chunks);
581-
// }
582-
583-
// grouped_by_exports_map = Some(grouped_by_exports);
584-
// } else {
585-
// for module in module_graph.modules().keys() {
586-
// let chunks = chunk_graph.get_module_chunks(*module);
587-
// let chunk_key = get_key(chunks.iter());
588-
// chunk_sets_in_graph.insert(chunk_key, chunks.clone());
589-
// }
590-
// }
591-
592-
// for chunks in chunk_sets_in_graph.values() {
593-
// let count = chunks.len();
594-
// chunk_sets_by_count
595-
// .entry(count)
596-
// .and_modify(|set| set.push(chunks.clone()))
597-
// .or_insert(vec![chunks.clone()]);
598-
// }
599-
600-
// (
601-
// chunk_sets_in_graph,
602-
// chunk_sets_by_count,
603-
// grouped_by_exports_map,
604-
// )
605-
// }
606558
}
607559

608560
async fn merge_matched_item_into_module_group_map(

0 commit comments

Comments
 (0)