Avatar for the swc-project user
swc-project
swc
BlogDocsChangelog

Performance History

Latest Results

chore: update fixture structure
06-26-chore/rc-test
12 hours ago
fix(es/minifier): Eliminate unused classes with cyclic references (#11963) ## Description The minifier keeps classes that are only reachable through a cyclic reference to each other, even when the whole cluster is unused; `terser` removes them. Reproduced in #11934. The bug is in the DCE tree-shaker (`swc_ecma_transforms_optimization::simplify::dce`), which the minifier runs through `perform_dce`. ### Root cause `Data::subtract_cycles` cancels the internal edges of a strongly-connected component — making its members eliminable — only when no node in the component is a top-level entry and none has an incoming edge from outside it. In `Analyzer::visit_class_decl` the `extends` clause was visited *before* the class identifier was pushed onto the dependency path (`with_ast_path`). A reference seen with an empty path is recorded as a top-level entry, so for `class B extends A {}` the superclass `A` was pinned as an entry. That kept the otherwise-unreachable `A ⇄ B` cycle (formed by the method bodies) from being subtracted, so both classes survived. ### Fix `visit_class_decl` now attributes the `extends` edge to the subclass (inside the path) only when the superclass is a **backward reference to an already-initialized class**, tracked with a small per-scope `FxHashSet<Id>`. Forward references, non-identifier superclasses, and everything else keep the original behavior (visited outside the path, i.e. pinned as an entry). This preserves TDZ-observable cycles such as `class A extends B {} class B extends A {}` — which throws at definition time and must not be eliminated (there only `B → A` is a backward reference, so `B` stays pinned and both classes are kept). It also closes a latent hole in the same mechanism: a clean class in a cycle that is referenced by a kept, side-effectful sibling (e.g. a `static {}` block) could be dropped, leaving a dangling reference. A class whose definition has side effects is now marked as an entry, reusing the existing class-drop predicate (factored out as `class_def_is_side_effect_free`), so those cycles are preserved. ### Performance The change is confined to `dce/mod.rs` and is intentionally minimal: it does **not** touch the `VarInfo` edge-weight struct or the `subtract_cycles` hot loop. The only added work on the common path is one `FxHashSet<Id>` insert per class declaration. CodSpeed should be neutral. (An earlier, broader attempt — #11933 — grew the edge weight and added per-declarator bookkeeping, which regressed CodSpeed; this PR is scoped to the class-`extends` case to avoid that.) ### Tests In `tests/simplify_dce.rs`: - `class_extends_cycle_unused` — the repro; both classes are eliminated. Confirmed to **fail** without the fix (`git stash` on `dce/mod.rs`). - `class_extends_cycle_tdz_preserved` — `class A extends B {} class B extends A {}` is kept. - `class_extends_cycle_with_side_effect_preserved` — a cycle whose member has a `static {}` block is kept. `cargo test -p swc_ecma_transforms_optimization` and `cargo test -p swc_ecma_minifier` pass with no snapshot changes (including the terser execution tests). ## Related issue Closes #11934 Co-authored-by: Donny/강동윤 <kdy.1997.dev@gmail.com>
main
18 hours ago
fix(dce): handle unknown class members
baltasarblanco:fix/11934-dce-class-extends-cycle
19 hours ago
feat: expose react compiler lint diagnostics Co-Authored-By: Oz <oz-agent@warp.dev>
imjordanxd:feat/react-compiler-lint-diagnostics
2 days ago
Merge branch 'main' into fix/11934-dce-class-extends-cycle
baltasarblanco:fix/11934-dce-class-extends-cycle
2 days ago
Document minifier assumptions
kdy1/document-minifier-assumptions
2 days ago
feat: expose react compiler lint diagnostics Co-Authored-By: Oz <oz-agent@warp.dev>
imjordanxd:feat/react-compiler-lint-diagnostics
2 days ago

Latest Branches

CodSpeed Performance Gauge
0%
test(react-compiler): add build-pass fixtures for wrapped assignment targets#11967
12 hours ago
b553cdd
06-26-chore/rc-test
CodSpeed Performance Gauge
0%
fix(es/minifier): Eliminate unused classes with cyclic references#11963
19 hours ago
d597f48
baltasarblanco:fix/11934-dce-class-extends-cycle
CodSpeed Performance Gauge
0%
2 days ago
70ab42c
imjordanxd:feat/react-compiler-lint-diagnostics
© 2026 CodSpeed Technology
Home Terms Privacy Docs