Skip to content

Deploy March 3, 2026#5877

Merged
canova merged 45 commits intoproductionfrom
main
Mar 3, 2026
Merged

Deploy March 3, 2026#5877
canova merged 45 commits intoproductionfrom
main

Conversation

@canova
Copy link
Member

@canova canova commented Mar 3, 2026

Changes:

[fatadel] Fix crash when nativeSymbol index is out of bounds in assembly view (#5850)
[depfu[bot]] Update all Yarn dependencies (2026-02-25) (#5859)
[Nazım Can Altınova] Fix the color of dark mode back arrow svg (#5863)
[fatadel] Force canvas redraw when system theme changes (#5861)
[Nazım Can Altınova] Fix unhandled promise rejection in setupInitialUrlState (#5864)
[fatadel] Persist selected marker in URL and show sticky tooltip on load (#5847)
[Markus Stange] Implement the "collapse resource" transform with the help of the "collapse direct recursion" transform. (#5824)
[Markus Stange] Bump rollup from 2.79.2 to 2.80.0 (#5868)
[Markus Stange] Remove async attribute from module script tag. (#5870)
[Nazım Can Altınova] Update the docsify package that's used in the user documentation (#5872)
[Markus Stange] Share stackTable, frameTable, funcTable, resourceTable and nativeSymbols between threads (#5482)
[Nazım Can Altınova] Escape CSS URLs that are coming from profiles (#5874)
[fatadel] Update home page message for the other browser case (#5866)
[fatadel] Add support for ternaries in marker labels (#5857)
[Markus Stange] Reduce allocations for getStackLineInfo + getStackAddressInfo (#5761)

And special thanks to our localizers:

de: Ger
fy-NL: Fjoerfoks
it: Francesco Lodolo [:flod]
nl: Fjoerfoks
ru: berry
ru: Valery Ledovskoy
zh-TW: Pin-guang Chen

Firefox Profiler [bot] and others added 30 commits February 25, 2026 08:22
Co-authored-by: berry <igory.ygr200@gmail.com> (ru)
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Co-authored-by: Nazım Can Altınova <canaltinova@gmail.com>
The `fill` attribute of the <g> element was change properly but not the
<rect> fill.
dispatch(finalizeProfileView()) returns a Promise that was previously
discarded. Errors thrown synchronously inside it (e.g. from selectors
like computeReferenceCPUDeltaPerMs) were converted to rejected promises
by the async function, then escaped as "Uncaught (in promise)" instead
of being routed to the FATAL_ERROR state.

Adding .catch() dispatches fatalError() on failure so the error UI is
shown correctly. finalizeProfileView is still intentionally not awaited
since it handles long-running work like symbolication in the background.
Add a `marker` URL parameter that persists the selected marker index per thread, following the same pattern as transforms. When loading a shared profile URL with a selected marker, the marker chart scrolls to it and displays a sticky tooltip.

- Move selectedMarker from view state to URL state as a per-thread map
- Encode/decode the marker parameter in URL query strings
- Scroll the viewport to bring the selected marker into view on load
- Show a sticky tooltip anchored to the marker's canvas position
…lapse direct recursion" transform.

This simplifies the code considerably.

There is a slight behavior change in the case where there's an implementation
filter, see the change to the test. I think the new behavior makes more sense,
and it is consistent with the existing behavior of the collapse-direct-resource
transform.

I'm not worried about breaking URLs because the collapse resource transform
is only very rarely used, and the combination with an implementation filter
is probably even rarer.

This change also simplifies the creation of the new frame table: We don't
need to add any new frames, we can just swap out the func on all existing
frames whose original func is from the collapsed resource.
…lapse direct recursion" transform. (#5824)

This simplifies the code considerably.

There is a slight behavior change in the case where there's an
implementation filter, see the change to the test. I think the new
behavior makes more sense, and it is consistent with the existing
behavior of the collapse-direct-resource transform.

I'm not worried about breaking URLs because the collapse resource
transform is only very rarely used, and the combination with an
implementation filter is probably even rarer.

This change also simplifies the creation of the new frame table: We
don't need to add any new frames, we can just swap out the func on all
existing frames whose original func is from the collapsed resource.
Bumps [rollup](https://github.com/rollup/rollup) from 2.79.2 to 2.80.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/v2.80.0/CHANGELOG.md)
- [Commits](rollup/rollup@v2.79.2...v2.80.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 2.80.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [rollup](https://github.com/rollup/rollup) from 2.79.2 to 2.80.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rollup/rollup/blob/v2.80.0/CHANGELOG.md">rollup's
changelog</a>.</em></p>
<blockquote>
<h2>2.80.0</h2>
<p><em>2026-02-22</em></p>
<h3>Features</h3>
<ul>
<li>Throw when the generated bundle contains paths that would leave the
output directory (<a
href="https://redirect.github.com/rollup/rollup/issues/6277">#6277</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6277">#6277</a>:
Validate bundle stays within output dir (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/rollup/rollup/commit/d17ae15336a45c3c59b2a4aacac2b14186035d28"><code>d17ae15</code></a>
2.80.0</li>
<li><a
href="https://github.com/rollup/rollup/commit/d6dee5e99bb82aac0bee1df4ab9efbde455452c3"><code>d6dee5e</code></a>
Validate bundle stays within output dir (<a
href="https://redirect.github.com/rollup/rollup/issues/6277">#6277</a>)</li>
<li>See full diff in <a
href="https://github.com/rollup/rollup/compare/v2.79.2...v2.80.0">compare
view</a></li>
</ul>
</details>
<details>
<summary>Install script changes</summary>
<p>This version adds <code>prepare</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=rollup&package-manager=npm_and_yarn&previous-version=2.79.2&new-version=2.80.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/firefox-devtools/profiler/network/alerts).

</details>
Fixes #5869.

Module scripts are deferred by default per HTML spec section 4.12.1
(prepare a script algorithm): parser-inserted type=module scripts
without async go into the "list of scripts that will execute when the
document has finished parsing" (executed in section 13.2.7 "The end").

Adding async makes the script execute as soon as it downloads, which
can happen before DOM parsing completes, breaking document.getElementById
and similar DOM access in the main bundle.
We stopped using google analytics a very long time ago. But it looks
like the ga docsify plugin was still loaded even though it wasn't used.
This commit removes this plugin
This commit updates the docsify plugin to its latest released version,
v4.13.1. But it looks like this PR is not in this release yet:
docsifyjs/docsify#2586

Since it's nice to have it, these minified JS code has this PR applied
as well.
We use docsify in the user documentation. It looks like our plugin has
been out of date for a while.

This PR:
- Removes the unused ga docsify plugin. We stopped using google
analytics a very long time ago. But it looks like the ga docsify plugin
was still loaded even though it wasn't used.
- Updates the docsify plugin to its latest released version, v4.13.1.
But it looks like this PR is not in this release yet. This PR also cherry
picks the changes and manually applies on top of v4.13.1.
…Symbols across threads.

This makes func indexes etc valid globally instead of scoped per threads.
It also allows for smaller profiles because data doesn't have to be duplicated.
Symbolication is probably faster.

Selecting multiple threads, i.e. displaying a "merged thread", is now easier because
we no longer need to compute merged funcTables etc for the merged thread; the global
tables are already "merged".
This also also means that func index mapping during symbolication now works even if
multiple threads are selected. Fixes #5703.

This profile version comes both with a profile upgrader and with a URL upgrader,
because we have to adjust any func and resource indexes for transforms in the URL.
We also need to adjust any indexes in the redux state after compacting,
for example funcTable or resourceTable indexes used by transforms.

This patch also makes us adjust the source index in the URL after compaction.
Strictly speaking this fixes an existing bug, because the source table
was already being compacted.

It also fixes the bug where we weren't keeping track of the oldFuncCount properly
when splitting functions into private-window and non-private-window instances,
and weren't updating collapse-resource transforms correctly. Fixes #5793.
We compute the call node table based on the filtered thread, per thread.
But now that every thread contains the full stackTable with entries used
by all threads, this computation has become much more expensive.
But most of the time we are passing the same tables from the shared profile
info, so we can just do the work once and share it across threads.

This only fixes the case where none of the threads have a transform applied.
They'll end up passing the tables from the shared data and hit the memoization
cache.

If a thread has a transform, it'll pass different tables and not hit the cache.

We don't do anything to share work across two threads that happen to have the
same transforms.

This also doesn't fix the case where there's an implementation filter applied.

Here's how loading the profile https://share.firefox.dev/4bxDqu8 compares:

- Before sharing the tables: https://share.firefox.dev/4r0imRO (1.1 seconds)
- After sharing the tables, no global memoization: https://share.firefox.dev/4qNGp6m (1.8 seconds)
- After sharing the tables, with global memoization: https://share.firefox.dev/4rwkwso (1.3 seconds)
…threads.

Here's how loading the profile https://share.firefox.dev/4kbkjrU compares:

- Before sharing the tables: https://share.firefox.dev/4kh5i84 (1.1 seconds)
- After sharing the tables, no global memoization: https://share.firefox.dev/3NLn1IK (1.6 seconds)
- After sharing the tables, with global memoization: https://share.firefox.dev/3LNNuot (1.3 seconds)
Here's how loading the profile https://share.firefox.dev/4a0b88Y compares:

- Before sharing the tables: https://share.firefox.dev/4qeiVGu (1.1 seconds)
- After sharing the tables, no global memoization: https://share.firefox.dev/3NUEi27 (2.0 seconds)
- After sharing the tables, with global memoization: https://share.firefox.dev/4qcDQty (1.3 seconds)
mstange and others added 15 commits March 2, 2026 11:04
…ols between threads (#5482)

[Production](https://profiler.firefox.com/public/mhwwab4cf9v0hervrwat82pzt6v513bjjpk8eer/flame-graph/?globalTrackOrder=5d9g1b7feac83402rsvx0oph6mx3jtlx1kunx2iq&hiddenGlobalTracks=0wcewx3&hiddenLocalTracksByPid=2044-0wxa~9836-0wyf~10656-0wj~15300-0wz3~12100-0wxr~5188-0w47wyoyqyrytwyHq~5516-0w4~3408-0w8awSj~4280-0wC7~7424-0wSk~6212-0wCa~15736-0wxF7~7760-0wBj~7468-0wTo~2664-0wQj~6256-0wQj~13940-0wZr~17248-0w5~7204-0w4~6544-0w4~14068-0w4~15704-0w5~11936-0w4~10936-0w5~16236-0w5~6484-0w5~9228-0w4~14744-0w4~8896-0w5~11024-0w5~2596-0w5~10748-0w5~11328-0w4~2508-0w5~5760-0w5~5736-0w4&profileName=Firefox%20TodoMVC-jQuery-Sp3NUC-20260211-jQueryRewrite&symbolServer=http%3A%2F%2F127.0.0.1%3A3000%2F34vi73s1ayr2ddzsfibv7q469dqphzi2pvrk59w&thread=B.k&transforms=fs-m--async%2C-sync~df-810~df-6652~df-9223~df-6651~df-9549~df-9163~df-1711~df-40715~df-2457~df-10480~fs-m-suite-TodoMVC-jQuery~ff-9143~rec-9143~df-1681&v=13)
| [Deploy
preview](https://deploy-preview-5482--perf-html.netlify.app/public/mhwwab4cf9v0hervrwat82pzt6v513bjjpk8eer/flame-graph/?globalTrackOrder=5d9g1b7feac83402rsvx0oph6mx3jtlx1kunx2iq&hiddenGlobalTracks=0wcewx3&hiddenLocalTracksByPid=2044-0wxa~9836-0wyf~10656-0wj~15300-0wz3~12100-0wxr~5188-0w47wyoyqyrytwyHq~5516-0w4~3408-0w8awSj~4280-0wC7~7424-0wSk~6212-0wCa~15736-0wxF7~7760-0wBj~7468-0wTo~2664-0wQj~6256-0wQj~13940-0wZr~17248-0w5~7204-0w4~6544-0w4~14068-0w4~15704-0w5~11936-0w4~10936-0w5~16236-0w5~6484-0w5~9228-0w4~14744-0w4~8896-0w5~11024-0w5~2596-0w5~10748-0w5~11328-0w4~2508-0w5~5760-0w5~5736-0w4&profileName=Firefox%20TodoMVC-jQuery-Sp3NUC-20260211-jQueryRewrite&symbolServer=http%3A%2F%2F127.0.0.1%3A3000%2F34vi73s1ayr2ddzsfibv7q469dqphzi2pvrk59w&thread=B.k&transforms=fs-m--async%2C-sync~df-810~df-6652~df-9223~df-6651~df-9549~df-9163~df-1711~df-40715~df-2457~df-10480~fs-m-suite-TodoMVC-jQuery~ff-9143~rec-9143~df-1681&v=13)

Sharing the string table happened in #5481.
This PR makes us share the rest, and completes issue #3918.

Only samples and markers are still per-thread. I don't expect this to
change.
This includes allocation samples.

To do:

- [x] Fix type check and test failures
- [x] Upgrade the URL when upgrading the profile, to remap function
indexes etc. in the URL
- [x] When compacting during upload, apply translation tables to redux
state (e.g. update focus function indexes in URL)
- [x] Do something to address perf impact for computing the derived
thread (transforms and call node table computation happen per thread and
take longer if the tables are bigger because they now contain
information for all threads, should be able to reuse more of the
computed outputs in the thread derivation pipeline)
- [x] Memoize the computation of the implementation filtered thread
across threads
- [x] Adjust indexes in transforms when merging two different profiles
- [x] Add a paragraph to CHANGELOG-formats.md for the new version.
- [x] Add a test for merging profiles with applied transforms where we
actually check the filtered call tree

Potential follow-ups:
- Add a test checking that IndexIntoSourceTable indexes in the redux
state are updated after profile sanitizing
- Add a test checking that collapse-resource transforms aren't broken if
profile sanitizing adds elements to the funcTable
* Update home page message for the other browser case

1. Remove irrelevant comment.
2. Clarify that Firefox for desktop is needed for profiling which should eliminate confusion on, for example, Firefox for iOS.
3. Update download link, remove hardcoded en-US locale.

* Update translation key
Add support for ternaries in marker labels, eg `"{marker.data.canceled ? '❌' :  ''} {marker.data.delay}"`. What to know:

1. The conditional clause can refer to payload fields only, ie `marker.data.*`.
2. The condition is checked for truthiness only, no other conditional operator can be used. Truthiness = classical JS truthiness, ie not null/undefined/empty.
3. The true/false branches should be single-quoted string literals, `"marker.data.* ? 'yes' :  'no'"`.
Co-authored-by: Valery Ledovskoy <valery@ledovskoy.com> (ru)
Co-authored-by: Pin-guang Chen <petercpg@mail.moztw.org> (zh-TW)
Co-authored-by: Fjoerfoks <fryskefirefox@gmail.com> (nl)
Co-authored-by: Francesco Lodolo [:flod] <flod+pontoon@mozilla.com> (it)
Co-authored-by: Ger <ger_a@web.de> (de)
Co-authored-by: Fjoerfoks <fryskefirefox@gmail.com> (fy-NL)
Before: https://share.firefox.dev/3NnthpO
After: https://share.firefox.dev/45dMNv1

getStackLineInfo now allocates 46MB instead of 220MB (4.8x reduction),
and takes 146ms instead of 338ms (2.3x reduction), when opening the
source view for mozjemalloc.cpp on https://share.firefox.dev/3NnzEcF
[Production](https://share.firefox.dev/3NnzEcF) | [Deploy
preview](https://deploy-preview-5761--perf-html.netlify.app/public/fkmw9djz29ntsmaznezy93hhft85jy0zjrp5my8/calltree/?globalTrackOrder=0&invertCallstack&profileName=FullSp3Firefox-15x-symbolicated&thread=0&v=12)

On large profiles, opening the source view can cause large allocations
because we create `Set` objects for many stacks. In this PR I've
experimented with a more compact storage of a collection of sets.

Before: https://share.firefox.dev/3NnthpO
After: https://share.firefox.dev/45dMNv1

`getStackLineInfo` now allocates 46MB instead of 220MB (4.8x reduction),
and takes 146ms instead of 338ms (2.3x reduction), when opening the
source view for `mozjemalloc.cpp` on https://share.firefox.dev/3NnzEcF.
Updated locales: be, de, el, en-CA, en-GB, es-CL, fr, fur, fy-NL, ia,
it, nl, pt-BR, ru, sv-SE, tr, uk, zh-CN, zh-TW.
@canova canova requested a review from a team as a code owner March 3, 2026 18:46
@canova canova removed the request for review from a team March 3, 2026 18:46
@canova canova changed the title Deploy March 3, 2025 Deploy March 3, 2026 Mar 3, 2026
@canova canova merged commit 74b959c into production Mar 3, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants