We'll want to add a binary serialization soon, but we'll also keep the JSON serializatios as an option. This rename makes it clear which one you're calling.
Fixes firefox-devtools#6024. JsonSlabs is an alternative serialization format that's more efficient than JSON if the serialized object contains typed arrays. See https://github.com/mstange/json-slabs/ for details. Our profiles currently do not yet contain typed arrays. But with this in place, we can start converting more and more tables / columns to use typed arrays, and incrementally reap the efficiency benefits. This patch only adds the reading. In the UI, uploading / downloading profiles still uses JSON. For the profiler-edit node script, this patch also adds the "writing": If you run profiler-edit with `-o some-filename-ending-in.jslb`, then it will create a JSLB file (or a compressed JSLB file for .jslb.gz). --- The profile format "structure" is still the same as before. The format version is still given by profile.meta.preprocessedProfileVersion. Loading a JSLB file with a profile.meta.preprocessedProfileVersion that's higher than the currently known one will still complain, and attempt to reload the page or the service worker. This reload behavior is the primary reason why I want to get the "reading" part taken care of first, before we start converting any parts of the profile to get efficiency wins: The sooner we land this, the more likely it will be that, in the future, if somebody has a newer JSLB file but an old cached profiler, they'll see a useful error and get the auto-reload. Without this patch, loading a JSLB file in the profiler gives the following error: > Error: Unserializing the profile failed: Error: The profile array > buffer could not be parsed as a UTF-8 string. --- With all that said, it turns out there is already a case where this format gives an efficiency win, thanks to its "split out" feature that lets us put certain subtrees of the profile into separate JSON slabs: If the original JSON is larger 512MiB, we can split it into individual slabs which are each smaller than 512MiB, so the built-in JSON.parse will work and we don't have to use the slow streaming parse. Example: https://storage.googleapis.com/profiler-get-symbols-fixtures/large-speedometer3-profile.json.gz expands to a 577.74MB JSON file, https://storage.googleapis.com/profiler-get-symbols-fixtures/large-speedometer3-profile.jslb.gz expands to a 564.66MB JSLB file (slightly smaller because compacting removed unused strings) The JSLB file breaks down as follows: ``` idx type bytes elements path --- ------- ---------- -------- ------------------- 0 json 16.76 MiB - . (root) 1 json 264.82 MiB - .shared.stackTable 2 json 91.01 MiB - .shared.frameTable 3 json 8.47 MiB - .shared.funcTable 4 json 28.80 MiB - .shared.stringArray 5 json 154.80 MiB - .threads --- ------- ---------- -------- ------------------- 6 slabs 564.66 MiB ``` All of those individual JSON slabs are now under 512MiB. Loading the JSON file, uses streaming parser: https://share.firefox.dev/3PcB9vK (19 seconds) Loading the JSLB file, uses native JSON.parse: https://share.firefox.dev/3RkFcXs (2.3 seconds, 8.3x faster)
Merged
canova added a commit that referenced this pull request
Jun 16, 2026Changes: [Nazım Can Altınova] Fix call node context menu being hidden behind source view bottom box (#6045) [Nazım Can Altınova] Pass `--use-env-proxy` only when the node version is >= 24 (#6064) [fatadel] Upgrade @firefox-devtools/react-contextmenu to 5.2.4 (#6066) [Markus Stange] Switch profiler-edit from minimist to commander (#6065) [Markus Stange] Support reading profiles from JsonSlabs files (#6037) [Florian Quèze] Don't fail profile processing when a marker's stack field is not a backtrace (#6069) [fatadel] Replace the footer-links overlay with a settings menu (#6042) [fatadel] Upgrade @types/node to match Node 24 (#6070) [fatadel] Remove unused undici-types package (#6074) [cathaysia] Update isLocalURL to include LAN addresses, .local domains, and hostn… (#5973) [Markus Stange] Fix from-url with binary profiles (#6072) [fatadel] Upgrade to React 19 (#6067) [Markus Stange] Add an insertStackLabels helper. (#6076) [fatadel] Drive counter tooltips from a tooltipRows schema (#6023) [fatadel] Add TrackPower--tooltip-average-power-microwatt (#6080) [Markus Stange] Downgrade to React 19.1 to fix unusable dev build performance. (#6082) [Nazım Can Altınova] Add source map symbolication and source view support (#6018) [spokodev] fix(FilterNavigatorBar): clip overflow so many breadcrumbs do not expand the parent (#6085) [Markus Stange] Move paddings inside the tree header cells. (#6002) [Markus Stange] Add an --insert-label-frames argument to the profiler-edit tool (#5966) [Markus Stange] Stop printing "error: too many arguments" during tests. (#6088) [Markus Stange] More additions to profiler-edit, for sp3 profiles (#6009) [Nazım Can Altınova] Do not rely on localized texts in the settings menu tests (#6101) And special thanks to our localizers: be: Andrei Mukamolau de: Ger de: Michael Köhler de: Ralf Duehnfahr el: Jim Spentzos en-CA: chutten en-GB: Ian Neal es-CL: ravmn fr: Théo Chevalier fr: wy fur: Fabio Tomat fy-NL: Fjoerfoks ia: Melo46 it: Francesco Lodolo [:flod] nl: Mark Heijl ru: Valery Ledovskoy sr: Марко Костић (Marko Kostić) sv-SE: Andreas Pettersson tr: Grk tr: Selim Şumlu zh-CN: Olvcpr423 zh-TW: Pin-guang Chen