en un clic
rspack-sftrace
// Use sftrace, which is based on LLVM Xray instrumentation, to trace all Rust function calls. This can be used for performance analysis and troubleshooting.
// Use sftrace, which is based on LLVM Xray instrumentation, to trace all Rust function calls. This can be used for performance analysis and troubleshooting.
Use when optimizing performance for user-specified files, features, compilation stages, Rust crates, JavaScript plugins, graph processing, parser work, chunking, code generation, or memory/CPU hot paths in Rspack.
Create or update draft GitHub releases for the current project's main GitHub repository, then organize GitHub-generated release notes into user-friendly sections without rewriting release note items. Use for preparing, formatting, categorizing, creating, or updating GitHub release notes or draft releases.
Create the official Rspack release pull request for a stable or pre-release version bump. Use when the task is to prepare a formal release branch from a clean checkout, sync to the latest origin/main, run `./x version` with an optional `--pre alpha|beta|rc`, confirm the resulting JavaScript and Rust versions with the user, open the release PR, trigger Ecosystem CI, and report the PR plus workflow URLs.
Run Rspack's perf-guided optimization loop for `cases/all` and similar workloads: create an isolated worktree, build a profiling binding, benchmark with `RSPACK_BINDING`, collect and compare `perf` hotspots, implement small Rust changes, validate, commit, push, and trigger the Ecosystem Benchmark workflow after each pushed commit. Use this when the goal is iterative performance work, not just one-off profiling.
Run Rspack performance profiling on Linux using perf (with DWARF call stacks), generate perf.data, and analyze hotspots. Use when you need CPU-level bottlenecks, kernel symbol resolution, or repeatable profiling for rspack build/bench cases. Includes optional samply import with per-CPU threads for visualization, but primary analysis is perf-based.
| name | rspack-sftrace |
| description | Use sftrace, which is based on LLVM Xray instrumentation, to trace all Rust function calls. This can be used for performance analysis and troubleshooting. |
Use sftrace (LLVM XRay) to trace rspack's Rust function calls and convert them to perfetto protobuf format for performance analysis and troubleshooting.
Default workflow: run inside the target example directory (for example examples/react) and store all trace artifacts in that directory (not /tmp).
git clone https://github.com/quininer/sftrace
cd sftrace
cargo build --release
mkdir "$(./target/release/sftrace record --print-solib-install-dir)"
cp ./target/release/libsftrace.so "$(./target/release/sftrace record --print-solib-install-dir)/"
SFTRACE=1 pnpm build:binding:profiling
sftrace filter works on function symbols from an object file (for rspack, the binding .node file).
# Enter the target example directory first
cd examples/react
# Prefer the locally built profiling binding from the monorepo
BINDING_NODE="$(realpath ../../crates/node_binding/rspack.linux-x64-gnu.node)"
# Regex mode
sftrace filter -p "$BINDING_NODE" -r 'finish_modules|FlagDependencyExportsPlugin' -o sftrace.filter
# List mode (one regex per line)
# sftrace filter -p "$BINDING_NODE" --list symbols.list -o sftrace.filter
If your binding file name differs by platform, replace the .node path accordingly.
examples/react)Run from the target example directory and keep outputs local to that example.
cd examples/react
TRACE_DIR="sftrace-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$TRACE_DIR"
# Full trace
sftrace record -o "$TRACE_DIR/sf.log" -- pnpm build
# Filtered trace (requires sftrace.filter from step 3)
sftrace record -f sftrace.filter -o "$TRACE_DIR/sf.filtered.log" -- pnpm build
Convert sftrace log to pola dataframe.
cd examples/react
TRACE_DIR="sftrace-YYYYMMDD-HHMMSS" # replace with your run directory
sftrace convert --type pola "$TRACE_DIR/sf.log" -o "$TRACE_DIR/sf.pola"
This will generate two files, whose schema format is as follows:
This records all events from sftrace log.
| name | type | description |
|---|---|---|
| frame_id | uint64 | a unique id for each frame. a function's entry and exit have same frame id |
| parent | uint64 | point to previous frame id. zero means non-existent |
| tid | uint32 | thread id |
| func_id | uint64 | function unique id |
| time | nanoseconds | time elapsed since program started |
| kind | uint32 | event type, 1 is entry, 2 is exit, 3 is tail call |
This records the function symbol name and file path of func_id.
| name | type | description |
|---|---|---|
| func_id | uint64 | function unique id |
| name | string | function symbol name (demangled) |
| path | string | the file path and line number of function |
You can use python-polars to perform data analysis on sf.pola.
import polars as pl
sf = pl.scan_parquet("./sf.pola")
symtab = pl.scan_parquet("./sf.pola.symtab")
# Query the functions that appear most frequently
(
sf
.filter(pl.col("kind").eq(1))
.group_by("func_id")
.agg(pl.len().alias("func_count"))
.top_k(10, by="func_count")
.join(symtab, on="func_id")
.collect()
)
# Query the leaf frame of longest execution time
(
sf
.filter(~pl.col("frame_id").is_in(pl.col("parent").implode()))
.group_by("frame_id")
.agg([
pl.col("func_id").first(),
pl.col("time").filter(pl.col("kind").eq(1)).first().alias("entry_time"),
pl.col("time").filter(pl.col("kind").is_in([2, 3])).last().alias("exit_time"),
])
.filter(pl.col("exit_time").is_not_null())
.with_columns(pl.col("exit_time").sub("entry_time").alias("duration"))
.top_k(10, by="duration")
.join(symtab, on="func_id")
.collect()
)
Convert sftrace log to perfetto protobuf format.
cd examples/react
TRACE_DIR="sftrace-YYYYMMDD-HHMMSS" # replace with your run directory
sftrace convert "$TRACE_DIR/sf.log" -o "$TRACE_DIR/sf.pb.gz"
Visualization using viztracer
vizviewer --use_external_processor "$TRACE_DIR/sf.pb.gz"
Use this only for visualization.
sftrace filter matches function symbols by regex/list. It is not a first-class crate-path/module-path filter.