Skip to content

Conversation

@eth3lbert
Copy link
Contributor

@eth3lbert eth3lbert commented Jan 22, 2025

What does this PR try to resolve?

This PR adds an SVG renderer and allows users to choose between Canvas and SVG for rendering charts, which should hopefully resolve #8850.
image

Additional information

This does not guarantee a pixel-perfect match from the previous canvas-based solution, but I maintain it stays as close as possible.

@rustbot
Copy link
Collaborator

rustbot commented Jan 22, 2025

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-timings Area: timings S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 22, 2025
@eth3lbert eth3lbert force-pushed the timings-pipeline-svg branch from ac8c105 to 8761588 Compare January 22, 2025 14:18
@ehuss
Copy link
Contributor

ehuss commented Jan 22, 2025

For context, the original version of this used SVG. However, it was switched to canvas due to severe rendering performance problems on some systems and browsers. Has this been thoroughly tested on multiple browsers, and on systems with limited video cards, and different platforms?

@eth3lbert
Copy link
Contributor Author

For context, the original version of this used SVG.

Yeah, I noticed this part.

Has this been thoroughly tested on multiple browsers, and on systems with limited video cards, and different platforms?

No, I haven't tested it with legacy devices or systems, only the newest Firefox and Chrome. Testers and feedback are welcome :D

@weihanglo
Copy link
Member

However, it was switched to canvas due to severe rendering performance problems on some systems and browsers

Any chance to recall those legacy systems and browsers?

@ehuss
Copy link
Contributor

ehuss commented Jan 23, 2025

Any chance to recall those legacy systems and browsers?

It was probably a 2018-era Intel integrated UHD Graphics 630 or AMD Radeon Pro 560X with an Intel Core i7 (macbook). I think Firefox was one of the worst in performance, but Safari and Chrome were also pretty bad. I believe Firefox has improved its SVG rendering since then.

@eth3lbert
Copy link
Contributor Author

I believe Firefox has improved its SVG rendering since then.

For Firefox, although the SVG renders without issues, I encountered significant frame drops while scrolling on an M1 device when experimenting with this SVG solution for crates.io (which has 619 units in total). This is primarily due to those dependency lines. If I hide those dependency lines, everything works fine.

I'm not sure if this performance issue is solvable without modifying the presentation. If we only rendered dependency lines for on-screen blocks, the performance would improve significantly, although I'm not sure if this approach is desirable.

@rustbot

This comment has been minimized.

@weihanglo
Copy link
Member

@eth3lbert are you still interested in the experiment? Should we continue from here or write down a summary in #8850?

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 22, 2025
@rustbot
Copy link
Collaborator

rustbot commented Nov 22, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@eth3lbert
Copy link
Contributor Author

@eth3lbert are you still interested in the experiment? Should we continue from here or write down a summary in #8850?

@rustbot author

Yes, still interesting! But I am wondering if implementing this using the interactive approach, as mentioned in the #8850 (comment) would be more appropriate:

There are existing tools that use both approaches. For example, FlameGraph uses an SVG, and speedscope uses an interactive canvas interface.

Specifically, we could restrict the width and height and provide pan and zoom functionality (which could be implemented using either canvas or SVG). Furthermore, we could also provide the ability to change the size and add search functionality if needed. This approach would restrict memory usage to an acceptable level and potentially further improve performance. The drawback might be that users with large screens might lose the ability to view the whole graph at once and would need to zoom in. We could also provide a graph export ability for those interested in the entire graph. This, however, would change how the graph is shown and interacted with, and I am unsure if this aligns with the goal. Feedback is welcome! :D

@weihanglo
Copy link
Member

The drawback might be that users with large screens might lose the ability to view the whole graph at once and would need to zoom in.

This reminds me a property we discussed a while back (#t-cargo > ✔ Making timings chart scalable @ 💬): it is possible to set two different timings charts to identical scales for comparison. Not sure if the proposal will remove this or not.

That said, it might be a bit easier to implement now since the RenderContext provide an separation of data and presentation layer: #16282. We could probably have an unstable SVG timing report format for people to test :)

@weihanglo
Copy link
Member

Or we could have a button for people to switch between two modes 😆

@eth3lbert
Copy link
Contributor Author

That said, it might be a bit easier to implement now since the RenderContext provide an separation of data and presentation layer: #16282. We could probably have an unstable SVG timing report format for people to test :)

Thanks for the information, I'll take a look in the near future :D

Or we could have a button for people to switch between two modes 😆

Is this referring to canvas and SVG rendering, or to panning and zooming?

@weihanglo
Copy link
Member

For switching between SVG/canvas, but could also for other stuff. This is not strictly adhered with Cargo's stability guarantee I believe.

This allows users to choose between canvas and SVG rendering, and it defaults to canvas.
When rendering SVGs with a large number of units, Firefox becomes quite
janky during scrolling. This appears to be caused by dependency lines
that use merged paths and dashed styles. Therefore, this approach splits
them into multiple paths instead.
@eth3lbert eth3lbert force-pushed the timings-pipeline-svg branch from 8761588 to d4e9a7a Compare December 24, 2025 22:26
@rustbot
Copy link
Collaborator

rustbot commented Dec 24, 2025

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@eth3lbert
Copy link
Contributor Author

For switching between SVG/canvas

I've added this now! The CI failed, but it shouldn't be related to this PR. The scrolling jank in Firefox is also fixed on my end, so please give it a try and let me know what you think. :D

@eth3lbert
Copy link
Contributor Author

I also found that highlighting connected units on hover is less useful when there are many units. They might not all fit on the screen, which means you have to scroll a long way to find the connections. Plus, you might accidentally hover over other units while scrolling. Because of this, a different interface would be more helpful for showing these relations. For example, clicking a unit to show its connections in a side panel might provide a better UX.

@weihanglo
Copy link
Member

Windows GNU flakiness. Re-running

---- freshness_checksum::no_rebuild_when_rename_dir stdout ----
running `D:\a\cargo\cargo\target\debug\cargo.exe build -Zchecksum-freshness`

thread 'freshness_checksum::no_rebuild_when_rename_dir' (8768) panicked at tests\testsuite\freshness_checksum.rs:1148:32:
> called `Result::unwrap()` on an `Err` value: Os { code: 5, kind: PermissionDenied, message: "Access is denied." }

Comment on lines +811 to +820
<td>
<label>
<input type="radio" name="renderer" value="canvas" checked />
Canvas
</label>
<label>
<input type="radio" name="renderer" value="svg" />
SVG
</label>
</td>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I plan to make the SVG renderer the default, since it outperformed Canvas in my testing across Firefox, Chrome, and Safari!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested and really really impressive!

#15091 (comment)

Copy link
Member

@weihanglo weihanglo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this. The PR is so nice for both refactors and the SVG implementation.

I assume this doesn't need any team FCP:

  • It offers a switch between canvas and SVG rendering options. If anything broken, people can always switch back.
  • The default is still canvas.
  • The HTML report UI is for human not for machine, so we have more flexibility to change it.

I am excited to merge this right now! Really appreciate it!

View changes since this review

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also found that highlighting connected units on hover is less useful when there are many units. They might not all fit on the screen, which means you have to scroll a long way to find the connections. Plus, you might accidentally hover over other units while scrolling. Because of this, a different interface would be more helpful for showing these relations. For example, clicking a unit to show its connections in a side panel might provide a better UX.

Agree with side panel solution. That sounds pretty approachable.
I am not sure if it is easy to implement though, as currently we don't use any Web Frontend frame work, which may make it a bit hard to maintain

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried with CARGO_BUILD_ANALYSIS_ENABLED=true rustup run nightly target/debug/cargo build -Zsection-timings -Zbuild-analysis && target/debug/cargo report timings -Zbuild-analysis --open. The performance enhancement was so huge!

  • Google Chrome: Version 143.0.7499.170 (Official Build) (arm64)
  • Safari: Version 26.2 (20623.1.14.18.4)
  • Firefox: 145.0 (aarch64)
  1. Tried set the scale factor to 9.
  2. Chose the canvas renderer
    • Observed on Chrome and Safari, it was laggy and stopped rendering at some point.
    • Observed on Firefox it worked.
  3. Switched to the SVG renderer
    • All of them works well.
    • On Firefox the dependency line drawing was faster than the canvas renderer.

Here is the timing HTML: cargo-timing.html

@weihanglo weihanglo added this pull request to the merge queue Dec 25, 2025
Merged via the queue into rust-lang:master with commit c15cd9b Dec 25, 2025
76 of 87 checks passed
@eth3lbert eth3lbert deleted the timings-pipeline-svg branch December 25, 2025 22:18
bors added a commit to rust-lang/rust that referenced this pull request Dec 27, 2025
Update cargo submodule

17 commits in e91b2baa632c0c7e84216c91ecfe107c37d887c1..94c368ad2b9db0f0da5bdd8421cea13786ce4412
2025-12-13 16:29:21 +0000 to 2025-12-26 19:39:15 +0000
- fix(vendor): unpack from local-registry cache path (rust-lang/cargo#16435)
- feat(index): Stabilize pubtime (rust-lang/cargo#16372)
- Experiment: Render timing pipeline in SVG (rust-lang/cargo#15091)
- chore(triagebot): auto-label `Command-report` (rust-lang/cargo#16429)
- fix(sbom): Don't set CARGO_SBOM_PATH when empty (like stable)  (rust-lang/cargo#16419)
- chore(ci): report-timings to upload HTML report (rust-lang/cargo#16416)
- fix(report): get the same feature parity of `--timings` (rust-lang/cargo#16414)
- fix(docs): Document the only possible values for DEBUG in build scripts (rust-lang/cargo#16413)
- fix(log): emit fingeprint log also for no-rebuild unit (rust-lang/cargo#16408)
- Fix link to `doc_cfg` docs in cargo book (rust-lang/cargo#16404)
- Add best pratice for how to check in generated files (rust-lang/cargo#16405)
- test: Use a larger default term width (rust-lang/cargo#16403)
- Document more services and permissions of the cargo team (rust-lang/cargo#16402)
- fix(new): Improve quality of package name error messages (rust-lang/cargo#16398)
- feat(log): add more log events (rust-lang/cargo#16390)
- chore: bump to 0.95.0; update changelog (rust-lang/cargo#16395)
- Cache submodule into git db (rust-lang/cargo#16246)

r? ghost
@rustbot rustbot added this to the 1.94.0 milestone Dec 27, 2025
github-actions bot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Dec 28, 2025
Update cargo submodule

17 commits in e91b2baa632c0c7e84216c91ecfe107c37d887c1..94c368ad2b9db0f0da5bdd8421cea13786ce4412
2025-12-13 16:29:21 +0000 to 2025-12-26 19:39:15 +0000
- fix(vendor): unpack from local-registry cache path (rust-lang/cargo#16435)
- feat(index): Stabilize pubtime (rust-lang/cargo#16372)
- Experiment: Render timing pipeline in SVG (rust-lang/cargo#15091)
- chore(triagebot): auto-label `Command-report` (rust-lang/cargo#16429)
- fix(sbom): Don't set CARGO_SBOM_PATH when empty (like stable)  (rust-lang/cargo#16419)
- chore(ci): report-timings to upload HTML report (rust-lang/cargo#16416)
- fix(report): get the same feature parity of `--timings` (rust-lang/cargo#16414)
- fix(docs): Document the only possible values for DEBUG in build scripts (rust-lang/cargo#16413)
- fix(log): emit fingeprint log also for no-rebuild unit (rust-lang/cargo#16408)
- Fix link to `doc_cfg` docs in cargo book (rust-lang/cargo#16404)
- Add best pratice for how to check in generated files (rust-lang/cargo#16405)
- test: Use a larger default term width (rust-lang/cargo#16403)
- Document more services and permissions of the cargo team (rust-lang/cargo#16402)
- fix(new): Improve quality of package name error messages (rust-lang/cargo#16398)
- feat(log): add more log events (rust-lang/cargo#16390)
- chore: bump to 0.95.0; update changelog (rust-lang/cargo#16395)
- Cache submodule into git db (rust-lang/cargo#16246)

r? ghost
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Dec 28, 2025
Update cargo submodule

17 commits in e91b2baa632c0c7e84216c91ecfe107c37d887c1..94c368ad2b9db0f0da5bdd8421cea13786ce4412
2025-12-13 16:29:21 +0000 to 2025-12-26 19:39:15 +0000
- fix(vendor): unpack from local-registry cache path (rust-lang/cargo#16435)
- feat(index): Stabilize pubtime (rust-lang/cargo#16372)
- Experiment: Render timing pipeline in SVG (rust-lang/cargo#15091)
- chore(triagebot): auto-label `Command-report` (rust-lang/cargo#16429)
- fix(sbom): Don't set CARGO_SBOM_PATH when empty (like stable)  (rust-lang/cargo#16419)
- chore(ci): report-timings to upload HTML report (rust-lang/cargo#16416)
- fix(report): get the same feature parity of `--timings` (rust-lang/cargo#16414)
- fix(docs): Document the only possible values for DEBUG in build scripts (rust-lang/cargo#16413)
- fix(log): emit fingeprint log also for no-rebuild unit (rust-lang/cargo#16408)
- Fix link to `doc_cfg` docs in cargo book (rust-lang/cargo#16404)
- Add best pratice for how to check in generated files (rust-lang/cargo#16405)
- test: Use a larger default term width (rust-lang/cargo#16403)
- Document more services and permissions of the cargo team (rust-lang/cargo#16402)
- fix(new): Improve quality of package name error messages (rust-lang/cargo#16398)
- feat(log): add more log events (rust-lang/cargo#16390)
- chore: bump to 0.95.0; update changelog (rust-lang/cargo#16395)
- Cache submodule into git db (rust-lang/cargo#16246)

r? ghost
github-actions bot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Dec 29, 2025
Update cargo submodule

17 commits in e91b2baa632c0c7e84216c91ecfe107c37d887c1..94c368ad2b9db0f0da5bdd8421cea13786ce4412
2025-12-13 16:29:21 +0000 to 2025-12-26 19:39:15 +0000
- fix(vendor): unpack from local-registry cache path (rust-lang/cargo#16435)
- feat(index): Stabilize pubtime (rust-lang/cargo#16372)
- Experiment: Render timing pipeline in SVG (rust-lang/cargo#15091)
- chore(triagebot): auto-label `Command-report` (rust-lang/cargo#16429)
- fix(sbom): Don't set CARGO_SBOM_PATH when empty (like stable)  (rust-lang/cargo#16419)
- chore(ci): report-timings to upload HTML report (rust-lang/cargo#16416)
- fix(report): get the same feature parity of `--timings` (rust-lang/cargo#16414)
- fix(docs): Document the only possible values for DEBUG in build scripts (rust-lang/cargo#16413)
- fix(log): emit fingeprint log also for no-rebuild unit (rust-lang/cargo#16408)
- Fix link to `doc_cfg` docs in cargo book (rust-lang/cargo#16404)
- Add best pratice for how to check in generated files (rust-lang/cargo#16405)
- test: Use a larger default term width (rust-lang/cargo#16403)
- Document more services and permissions of the cargo team (rust-lang/cargo#16402)
- fix(new): Improve quality of package name error messages (rust-lang/cargo#16398)
- feat(log): add more log events (rust-lang/cargo#16390)
- chore: bump to 0.95.0; update changelog (rust-lang/cargo#16395)
- Cache submodule into git db (rust-lang/cargo#16246)

r? ghost
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
Update cargo submodule

17 commits in e91b2baa632c0c7e84216c91ecfe107c37d887c1..94c368ad2b9db0f0da5bdd8421cea13786ce4412
2025-12-13 16:29:21 +0000 to 2025-12-26 19:39:15 +0000
- fix(vendor): unpack from local-registry cache path (rust-lang/cargo#16435)
- feat(index): Stabilize pubtime (rust-lang/cargo#16372)
- Experiment: Render timing pipeline in SVG (rust-lang/cargo#15091)
- chore(triagebot): auto-label `Command-report` (rust-lang/cargo#16429)
- fix(sbom): Don't set CARGO_SBOM_PATH when empty (like stable)  (rust-lang/cargo#16419)
- chore(ci): report-timings to upload HTML report (rust-lang/cargo#16416)
- fix(report): get the same feature parity of `--timings` (rust-lang/cargo#16414)
- fix(docs): Document the only possible values for DEBUG in build scripts (rust-lang/cargo#16413)
- fix(log): emit fingeprint log also for no-rebuild unit (rust-lang/cargo#16408)
- Fix link to `doc_cfg` docs in cargo book (rust-lang/cargo#16404)
- Add best pratice for how to check in generated files (rust-lang/cargo#16405)
- test: Use a larger default term width (rust-lang/cargo#16403)
- Document more services and permissions of the cargo team (rust-lang/cargo#16402)
- fix(new): Improve quality of package name error messages (rust-lang/cargo#16398)
- feat(log): add more log events (rust-lang/cargo#16390)
- chore: bump to 0.95.0; update changelog (rust-lang/cargo#16395)
- Cache submodule into git db (rust-lang/cargo#16246)

r? ghost
github-actions bot pushed a commit to rust-lang/stdarch that referenced this pull request Jan 1, 2026
Update cargo submodule

17 commits in e91b2baa632c0c7e84216c91ecfe107c37d887c1..94c368ad2b9db0f0da5bdd8421cea13786ce4412
2025-12-13 16:29:21 +0000 to 2025-12-26 19:39:15 +0000
- fix(vendor): unpack from local-registry cache path (rust-lang/cargo#16435)
- feat(index): Stabilize pubtime (rust-lang/cargo#16372)
- Experiment: Render timing pipeline in SVG (rust-lang/cargo#15091)
- chore(triagebot): auto-label `Command-report` (rust-lang/cargo#16429)
- fix(sbom): Don't set CARGO_SBOM_PATH when empty (like stable)  (rust-lang/cargo#16419)
- chore(ci): report-timings to upload HTML report (rust-lang/cargo#16416)
- fix(report): get the same feature parity of `--timings` (rust-lang/cargo#16414)
- fix(docs): Document the only possible values for DEBUG in build scripts (rust-lang/cargo#16413)
- fix(log): emit fingeprint log also for no-rebuild unit (rust-lang/cargo#16408)
- Fix link to `doc_cfg` docs in cargo book (rust-lang/cargo#16404)
- Add best pratice for how to check in generated files (rust-lang/cargo#16405)
- test: Use a larger default term width (rust-lang/cargo#16403)
- Document more services and permissions of the cargo team (rust-lang/cargo#16402)
- fix(new): Improve quality of package name error messages (rust-lang/cargo#16398)
- feat(log): add more log events (rust-lang/cargo#16390)
- chore: bump to 0.95.0; update changelog (rust-lang/cargo#16395)
- Cache submodule into git db (rust-lang/cargo#16246)

r? ghost
github-actions bot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Jan 8, 2026
Update cargo submodule

17 commits in e91b2baa632c0c7e84216c91ecfe107c37d887c1..94c368ad2b9db0f0da5bdd8421cea13786ce4412
2025-12-13 16:29:21 +0000 to 2025-12-26 19:39:15 +0000
- fix(vendor): unpack from local-registry cache path (rust-lang/cargo#16435)
- feat(index): Stabilize pubtime (rust-lang/cargo#16372)
- Experiment: Render timing pipeline in SVG (rust-lang/cargo#15091)
- chore(triagebot): auto-label `Command-report` (rust-lang/cargo#16429)
- fix(sbom): Don't set CARGO_SBOM_PATH when empty (like stable)  (rust-lang/cargo#16419)
- chore(ci): report-timings to upload HTML report (rust-lang/cargo#16416)
- fix(report): get the same feature parity of `--timings` (rust-lang/cargo#16414)
- fix(docs): Document the only possible values for DEBUG in build scripts (rust-lang/cargo#16413)
- fix(log): emit fingeprint log also for no-rebuild unit (rust-lang/cargo#16408)
- Fix link to `doc_cfg` docs in cargo book (rust-lang/cargo#16404)
- Add best pratice for how to check in generated files (rust-lang/cargo#16405)
- test: Use a larger default term width (rust-lang/cargo#16403)
- Document more services and permissions of the cargo team (rust-lang/cargo#16402)
- fix(new): Improve quality of package name error messages (rust-lang/cargo#16398)
- feat(log): add more log events (rust-lang/cargo#16390)
- chore: bump to 0.95.0; update changelog (rust-lang/cargo#16395)
- Cache submodule into git db (rust-lang/cargo#16246)

r? ghost
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-timings Area: timings S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cargo timings graph is broken in Firefox

4 participants