Replies: 1 comment 3 replies
-
|
Nice, I guess this work is part done (no integration with inner graph yet). I guess an alternative to integrating with inner graph would be to mark the callsites with a pure comment to let the swc minimizer remove those functions? Will inner graph integration come before v2? |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Implementation PR: Rspack #12559
Summary
Introduce support for cross-module function call optimization in Rspack. This allows function calls to be treated as side-effect-free (pure) based on external metadata or annotations, enabling more aggressive tree-shaking.
A function can be identified as "pure" via:
/* @__NO_SIDE_EFFECTS__ */annotation at the definition site.rspack.config.js.While this RFC focuses on function calls, the architecture is designed to extend to other cross-module analyses (e.g., member access or assignments) in the future.
Motivation
Rspack currently relies on SWC’s built-in side-effect analysis. This analysis is restricted to the scope of a single module and is intentionally conservative, leading to suboptimal tree-shaking in several scenarios:
/* @__PURE__ */.obj.prop) is treated as a side effect because the engine cannot guarantee the absence of a "getter" with side effects.Current Side-Effect Strategy
Rspack currently categorizes side-effect signals into two levels:
package.json("sideEffects": false) ormodule.rules. If a module is marked side-effect-free, Rspack skips analysis for the module and its dependencies.The Chaining Problem:
If module
A -> B -> C -> Dexists, and onlyDcontains a side effect, the entire chainA-B-C-Dwill be bundled even ifB's exports are never used. This ensures that the side effects inDare executed, but it often leads to "bloated" bundles where developers wonder why unused modules are included.Real-world Scenarios
cssfunction call is always treated as a side effect. In large component libraries, this prevents tree-shaking for nearly every component, even if unused.connectfromreact-reduxare used at the top level. Without cross-module purity info, the HOC call prevents the component from being removed.Prior Arts
/* @__NO_SIDE_EFFECTS__ */.manualPureFunctionsin configuration and implemented the/* @__NO_SIDE_EFFECTS__ */annotation.Detailed Design
We propose three methods to inform Rspack about side effects free functions:
1.
/* @__NO_SIDE_EFFECTS__ */AnnotationThis is the safest method as the intent is declared at the source. It supports various declaration styles:
asyncandgenerator).2. Configuration-based Marking
For third-party libraries (e.g.,
node_modules) where source modification is impossible, we provide amodule.rulesinterface:Note: This is a powerful but "dangerous" configuration. Rspack will attempt to validate if the identifier exists and is indeed a function to mitigate misconfiguration.
3. Optimization Pipeline
To support cross-module analysis, the side-effect detection logic must be decoupled from the initial
parsephase, as cross-module context is not yet available.Step A: Collection (Parse Phase)
During parsing, we record "potential side effects free statements" and establish a mapping between the statement and its
ESMImportSpecifierDependency.Step B: Analysis (FinishModules Phase)
Once all modules are processed, we iterate through the potential side effects free statements:
sideEffectFree.Integration with Inner Graph
Rspack’s InnerGraph optimization tracks variable usage. We will refactor InnerGraph to leverage this cross-module side effects free information. If a variable is initialized by a side effects free function call and that variable is not used, InnerGraph can safely remove the statement.
Example of InnerGraph Transformation:
If
heavyTaskis verified as pure across modules:This allows the minimizer (e.g., Terser or SWC) to perform dead-code elimination (DCE) effectively.
Future Extensions
Beta Was this translation helpful? Give feedback.
All reactions