Skip to content

fix(assets): fall back to bare-tag grouping for legacy tags in model_type mode - #14217

Closed
claude[bot] wants to merge 64 commits into
mainfrom
fix/assets-bare-tag-model-type-fallback
Closed

fix(assets): fall back to bare-tag grouping for legacy tags in model_type mode#14217
claude[bot] wants to merge 64 commits into
mainfrom
fix/assets-bare-tag-model-type-fallback

Conversation

@claude

@claude claude Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Requested by Simon P · Slack thread

Summary

Fixes a bug where a legacy bare-tagged model asset would silently disappear from the model library sidebar once the backend advertised model_type: support, instead of falling back to legacy bare-tag grouping.

Changes

  • What: Before this change, modelFolderFromTag returned undefined for any tag that didn't carry the model_type: prefix as soon as modelTypeMode was true. buildModelBuckets treats a tag list with no resolved folder as "uncategorized" and drops the asset with a console.warn, so a model still carrying a legacy bare tag (e.g. checkpoints instead of model_type:checkpoints) vanished from the sidebar entirely on a model_type:-capable backend. The fix makes modelFolderFromTag fall back to the existing legacy bare-tag grouping logic (same as the non-modelTypeMode path) whenever a tag doesn't carry the model_type: prefix, regardless of modelTypeMode. Changed in src/platform/assets/services/assetService.ts.
  • Breaking: none

How

  • modelFolderFromTag(tag, modelTypeMode) in src/platform/assets/services/assetService.ts now only special-cases tags that actually start with MODEL_TYPE_TAG_PREFIX; any other tag (bare or namespaced-but-unrecognized) falls through to the same bare-tag/top-level-segment grouping used when modelTypeMode is false.
  • Added an e2e scenario, Model library sidebar - asset mode with a legacy bare tag, in browser_tests/tests/sidebar/modelLibraryAssetMode.spec.ts, plus a matching fixture (MODEL_TYPE_CHECKPOINT_LEGACY_TAG in browser_tests/fixtures/data/assetFixtures.ts): a bare-tagged asset that still carries a loader_path, walked with supports_model_type_tags: true, asserting it still renders in the checkpoints folder rather than being dropped.
  • Also extended the existing unit coverage in src/platform/assets/services/assetService.test.ts with a case for the same regression (verified it fails against the pre-fix code, returning [] instead of the expected bucketed asset), since that file already exercises buildModelBuckets/modelFolderFromTag directly.

Review Focus

  • This is stacked on test(assets): e2e coverage for the assets-mode model library sidebar #13574 and targets its branch (synap5e/test/assets-sidebar-e2e) rather than main.
  • Fixes the bug flagged in this review comment on test(assets): e2e coverage for the assets-mode model library sidebar #13574: "the sidebar code violates it [AC3]... modelFolderFromTag(tag, modelTypeMode) returns undefined for any non-namespaced tag once modelTypeMode is true... buildModelBuckets then... drops the asset with a console.warn."
  • Could not run the full Playwright e2e suite in this environment (no local ComfyUI backend to serve http://localhost:5173 for test:browser:local). Verified instead with: pnpm typecheck (clean), eslint on changed files (clean), pnpm exec playwright test ... --list (new test resolves correctly, no syntax errors), and the full Vitest unit suite for assetService.test.ts (66/66 passing, including a manual revert of the fix to confirm the new unit test fails on pre-fix code).

Test plan

  • pnpm typecheck clean
  • pnpm exec eslint on changed files clean
  • pnpm exec vitest run src/platform/assets/services/assetService.test.ts — 66/66 passing
  • New unit test confirmed to fail on pre-fix code (regression proof)
  • pnpm exec playwright test browser_tests/tests/sidebar/modelLibraryAssetMode.spec.ts --list resolves the new e2e scenario with no errors
  • Full Playwright e2e run against a live backend — not feasible in this environment, not executed

Generated by Claude Code

synap5e added 30 commits July 24, 2026 09:04
Group the asset-mode Model Library by namespaced model_type:* tags. When an
asset carries model_type:* tags, the stripped values are the authoritative
categories and all other tags are disregarded; otherwise fall back to the
legacy bare-tag top-level grouping. A shared getAssetCategories helper keeps
the "By type" nav and category filtering in agreement.

Resolve node-provider lookup from the same tags via getAssetNodeCategory:
prefer the most specific (deepest parent/child) candidate so a flat
model_type:LLM does not shadow a resolvable hierarchical tag, and strip the
model_type: prefix before the modelNodeMappings lookup.
Drive the model_type: grouping/resolution off the backend-reported
supports_model_type_tags capability (getServerFeature) instead of sniffing
tags per asset. Default false preserves the legacy bare-tag grouping, so a
backend that does not declare the capability is unchanged. When the flag is
true, assets group by their model_type: values and an uncovered asset (no
model_type: tag) still routes by its bare tags.

The thread-through is a modelTypeMode flag on getAssetCategories /
getAssetNodeCategory / filterByCategory (keeping them pure); call sites read
the capability via useFeatureFlags.
Unwrap the if (isCloud) gate in assetsStore getModelState so the asset-mode
Model Library works on non-cloud distributions (it previously returned an
empty no-op store off-cloud, leaving the library blank even with the asset
API enabled). Scoped to the model-asset store only; the rest of the isCloud
forks are out of scope here.
The card type badge derived from the first raw non-models tag, so in
model_type mode it rendered the literal `model_type:checkpoints`. Route it
through a model_type-aware getAssetTypeBadge and key the display cache on the
flag so a late-arriving feature flag re-derives the badge. Also adds
docstrings to the tag helpers to satisfy coverage.
Also realigns the card type badge to the same rule: keep the existing
"first non-models tag" selection and only strip the model_type: namespace
prefix, rather than reordering to prefer the model_type: value. So an asset
like [models, foo, model_type:bar] still shows foo, while
[models, model_type:checkpoints] shows checkpoints. Title (primaryCategoryTag)
strips the same prefix when the flag is on.
…NodeFromAsset

main (#12765) renamed createModelNodeFromAsset -> resolveModelNodeFromAsset.
Re-apply FE-1076's flag-gated node-category resolution there: use
getAssetNodeCategory(asset, flags.supportsModelTypeTags) instead of the inline
first-non-reserved-tag lookup, so a model_type:* tag resolves the loader when
the supports_model_type_tags flag is on.
Importing MODELS_TAG/MISSING_TAG from assetService made this leaf util pull
the assetService -> i18n (createI18n) chain. Test suites that import
assetMetadataUtils (e.g. useAssetFilterOptions, AssetsSidebarListView) with a
minimal vue-i18n mock then failed to load. Define the two reserved-tag
literals locally so the util has no heavy transitive dependency.
Add afterEach(vi.restoreAllMocks) so the console.error spy doesn't persist
across tests (CodeRabbit nit).
An incidental hierarchical tag (e.g. a user-added foo/bar) could outrank
an authoritative model_type:vae in node-category resolution, targeting the
wrong provider or failing with NO_PROVIDER. Resolution now tries category
candidates most-specific-first and takes the first that maps to a provider,
so the deepest resolvable path still wins but unresolvable tags fall through.
In modelTypeMode the card badge and modal title now key off the same
model_type: value the asset groups under, so they can no longer diverge
from the grouping (review consensus on FE-1076). Loader-node resolution
demotes bare tags unrelated to any model_type: value to trailing
fallbacks: they can no longer pre-empt an authoritative resolvable
model_type: however deep they are, while related hierarchical twins
(LLM/Qwen-VL over flat model_type:LLM) keep winning.

Also: getAssetModelType can no longer return a raw model_type: literal
(kills the prefixed round-trip through edit widgets), modelTypeMode is
now a required parameter so new call sites must choose explicitly,
malformed empty model_type: tags produce no badge, per-asset flag reads
hoisted, and a test pins the local reserved-tag mirrors to
assetService's canonical values.
A refresh that fails before its first batch commits now mirrors the
error onto the committed state consumers actually read, instead of
dying silently on the discarded pending state. Pagination stops only
when a full page repeats the previous page verbatim (ignored-offset
signature); an all-duplicate page whose content merely shifted keeps
walking so later pages still load. Teardown of a stale request can no
longer evict a newer request's single-flight entries after an
interleaved invalidation.
Adversarial review follow-ups: an offset-ignoring backend that reorders
its responses could alternate two page orderings and defeat the
repeated-page check forever, so the walk now also remembers every served
page signature and treats a run of no-new-ID full pages as exhausted.
Modal titles for uncovered assets keep their legacy verbatim tag (only
covered assets retitle to their model_type value), restoring the
pre-alignment behavior the batch accidentally changed, and namespace
residue like a malformed empty model_type: can no longer leak into
titles, nav items, or categories.
A shared-root asset tagged with several model_type values groups under
each of them, but its badge and a node-typed picker's title keyed off
only the first value, so viewing it under its second category showed the
first category's label. Cards now badge every authoritative model_type
value, and a node-typed picker titles off the requested node's category
instead of guessing from the first asset.
An asset tagged with both `model_type:LLM` and a bare `LLM` yielded the
same category twice in the candidate list; deduplicate the tier-1 values
so a provider is only ever tried once per distinct category.

Flat output pagination stopped on the first all-duplicate page, so a
pagination window shifted by concurrent writes could hide later unseen
assets. Reuse the model-category walk's no-progress tolerance for both
walks instead of duplicating the counter, letting a bounded run of
all-duplicate pages be traversed while still guaranteeing termination.
Prefix the discovery folder_name with model_type: on model import and on
model-type edits, gated on the supports_model_type_tags backend capability.
Default off writes the legacy bare directory-path tag unchanged, so this is a
no-op until the backend declares the cutover; the flag is the same authoritative
signal FE-1076 grouping reads.

The FE writes only the single selected folder_name's model_type: form; the
backend keeps the bare directory-path twin in sync (and forward-expands shared
paths), so the edit path manages just the model_type: tags and the resolver read
path is untouched. Mirrors the read side: an uncovered asset with no model_type:
tag still routes by its bare tag.
Assert the import-by-URL path namespaces only the tag (model_type:<folder_name>)
while user_metadata.model_type stays the bare folder_name, since that value
still feeds download tracking, category refresh, and the progress label.
The required-type guard and imported-type label compared the bare folder_name
against raw asset tags, so a namespaced model_type:<folder> tag was treated as a
type mismatch (and leaked the raw prefix into the mismatch label). Strip the
model_type: prefix before comparing/labelling so a namespaced tag satisfies the
required type. Not reachable in production (the dual-write keeps the bare twin),
but hardens the import path against a namespaced-only asset.
Matches the read-path helpers: new call sites must choose the tag mode
explicitly instead of silently inheriting legacy behavior.
Re-typing a multi-type asset previously replaced its entire model_type:
tag set, silently destroying the other type memberships. Replace only the
primary membership (its model_type tag and stale bare twin), keeping
siblings intact. Primary is the lexicographically-first model_type value
so the choice is deterministic regardless of backend tag order, and the
edit dropdown displays that same primary. Extract the selection into one
shared helper and privatize the unused tag-prefix export.
Retagging a model rewrites its asset tags, but core is filesystem-backed
and does not yet move the file to match the new type, so an edit would
leave the tag and the on-disk location diverged. Gate the model type
dropdown to cloud builds; on core the field renders the existing
read-only label. Revert once core implements move-on-retag (or the asset
system no longer requires the file move).
Toasts teleport to body but were missing from the reka outside-layer
allowlist, so a non-modal dialog (e.g. Settings) dismissed itself when
focus recovery landed on a toast's close button. This happens whenever an
action button disables itself while its request is in flight and the
request fails: the browser drops focus from the disabled button and it can
resurface on the error toast. Latent on main; deterministic once the
sidebar rework shifted chunk timing enough for the loading state to render
before the failure response.
…(FE-1142)

Add a hidden, experimental Comfy.Assets.ModelLibraryAssetView setting that
controls whether the model library opens the asset browser or the sidebar,
defaulting to the asset browser on Cloud and the sidebar on Core. The
model-library toggle now reads this setting instead of Comfy.Assets.UseAssetAPI,
decoupling the sidebar-vs-asset-browser view from Asset API enablement so the
asset-backed view stays reachable on Core for testing without forcing the
cutover.
Derive folders from model_type: tags and use loader_path for the tree,
widget value, and viewMetadata. Gate local-disk metadata/preview reads
on !isCloud.

The models tag is walked once and bucketed per category (multi-category
assets land in each), memoized behind a request id so an in-flight walk
cannot repopulate an invalidated cache. Assets with a null loader_path
are unloadable (orphans) and are dropped with a warning rather than
minting a widget value from the deprecated name field; bare-tag backends
that predate loader_path keep the name fallback.
Manual refresh now kicks off POST /assets/seed (fire-and-forget, 409
tolerated, skipped on Cloud and on the legacy listing path) alongside the
immediate re-load of known server state. The scan's fast phase already
persists the category tags and loader filenames the sidebar needs, and the
backend announces it with the assets.seed.fast_complete websocket event, so
the store re-loads previously loaded folders on that event instead of
polling /assets/seed/status (which cannot distinguish the fast phase from
enrichment).
In asset mode every folder resolves from one cached walk, so load all
folders on sidebar mount: search and badge counts are complete from the
start and the load-all button becomes redundant (hidden; it remains for the
request-per-folder legacy path, where AutoLoadAll stays the opt-in). Log
when a scan's fast phase discovered new files, since the sidebar now
updates itself and the console note is the only trace of why.
Search results were a snapshot filled inside handleSearch, so a reload
(e.g. a completed scan discovering new files) updated the store without the
filtered tree ever re-running. Filter via a computed over the store instead,
and expand results from a watch so late-arriving matches unfold too.
…ions

/experiment/models returns each folder's raw registered allowlist; an
empty array means match-all. The asset walk filters folder contents by the
registered set verbatim, substituting an FE-owned copy of core's default
supported_pt_extensions when the allowlist is empty or the field is absent
(older backends). This reproduces the legacy sidebar's global-set display
behavior for match-all folders and extensions-less backends — nothing that
was hidden starts showing — while registered allowlists let exotic folders
(e.g. .gguf) surface their actual models. The legacy listing keeps its
historical server-side filter untouched.
synap5e and others added 6 commits July 24, 2026 14:25
- assert negative membership, no model_type: label leak, flag-absent
  default, and orphan (loader_path: null) exclusion
- pin the flag-on/no-loader_path cutover window (BE-4728) with a
  dedicated fixture and empty-tree spec so the cross-repo ordering
  dependency fails visibly in CI
- swap snapshot-then-assert sites to expect.poll and replace positional
  folder assertions with an ordered-text assertion per flake rules
- synchronize the degraded-walk expansion retry on its 500 response
- share the assets.seed.fast_complete wire constant between service and
  specs; default createCoreModelAsset overrides to {}

Specs authored against mocked routes; not fully verified locally (app
boot exceeds the fixture timeout under load). Routing spec passed 3/3;
lint, typecheck, knip, and unit tests pass.
…load

Search expansion ran only when the query committed, so a folder whose
first match arrived from a later reload (a scan completing while the
search was active) rendered collapsed and hid the result. Expand result
folders once per key instead: newly appearing folders open, folders the
user collapsed stay collapsed, and an unchanged tree costs no expand
pass.
…type mode

modelFolderFromTag returned undefined for any non-namespaced tag once a
backend advertised supports_model_type_tags, so buildModelBuckets dropped
the asset entirely (with a console.warn) instead of falling back to the
legacy bare-tag grouping used on older backends. A legacy bare-tagged
model would silently vanish from the sidebar.

Add e2e coverage in modelLibraryAssetMode.spec.ts and a unit test for the
underlying bucketing behavior.
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jul 28, 2026
@claude
claude Bot requested a review from AustinMroz July 28, 2026 20:14
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

🎨 Storybook: ✅ Built — View Storybook

Details

⏰ Completed at: 07/29/2026, 01:59:04 AM UTC

Links

🎭 Playwright: ✅ 1759 passed, 0 failed · 1 flaky

📊 Browser Reports
  • chromium: View Report (✅ 1738 / ❌ 0 / ⚠️ 1 / ⏭️ 5)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 18 / ❌ 0 / ⚠️ 0 / ⏭️ 0)

📦 Bundle: 8.15 MB gzip 🟢 -132 B

Details

Summary

  • Raw size: 34.2 MB baseline 34.2 MB — 🟢 -553 B
  • Gzip: 8.15 MB baseline 8.15 MB — 🟢 -132 B
  • Brotli: 5.63 MB baseline 5.63 MB — 🟢 -24 B
  • Bundles: 420 current • 420 baseline • 143 added / 143 removed

Category Glance
Data & Services 🟢 -525 B (3.42 MB) · Utilities & Hooks 🟢 -28 B (369 kB) · Vendor & Third-Party ⚪ 0 B (15.7 MB) · Other ⚪ 0 B (12.5 MB) · Graph Workspace ⚪ 0 B (1.28 MB) · Panels & Settings ⚪ 0 B (551 kB) · + 5 more

App Entry Points — 3.63 kB (baseline 3.63 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-CGepZggp.js (new) 3.63 kB 🔴 +3.63 kB 🔴 +1.82 kB 🔴 +1.57 kB
assets/index-lKgzZ4cS.js (removed) 3.63 kB 🟢 -3.63 kB 🟢 -1.82 kB 🟢 -1.6 kB

Status: 1 added / 1 removed

Graph Workspace — 1.28 MB (baseline 1.28 MB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-Bi6AQ3c6.js (removed) 1.28 MB 🟢 -1.28 MB 🟢 -275 kB 🟢 -207 kB
assets/GraphView-C4bvruu3.js (new) 1.28 MB 🔴 +1.28 MB 🔴 +275 kB 🔴 +207 kB

Status: 1 added / 1 removed / 1 unchanged

Views & Navigation — 112 kB (baseline 112 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-BIuYeNWP.js (new) 25 kB 🔴 +25 kB 🔴 +6.25 kB 🔴 +5.54 kB
assets/CloudSurveyView-ORaMD6oZ.js (removed) 25 kB 🟢 -25 kB 🟢 -6.25 kB 🟢 -5.54 kB
assets/CloudLoginView-DinD2SaU.js (removed) 11.6 kB 🟢 -11.6 kB 🟢 -3.14 kB 🟢 -2.75 kB
assets/CloudLoginView-kjVGqabq.js (new) 11.6 kB 🔴 +11.6 kB 🔴 +3.14 kB 🔴 +2.76 kB
assets/CloudSignupView-6j9XEg0q.js (removed) 9.96 kB 🟢 -9.96 kB 🟢 -2.81 kB 🟢 -2.47 kB
assets/CloudSignupView-D82ZAV_D.js (new) 9.96 kB 🔴 +9.96 kB 🔴 +2.81 kB 🔴 +2.47 kB
assets/CloudLayoutView-CIn4iYpv.js (removed) 9.54 kB 🟢 -9.54 kB 🟢 -2.35 kB 🟢 -2.02 kB
assets/CloudLayoutView-w3CYkeBL.js (new) 9.54 kB 🔴 +9.54 kB 🔴 +2.35 kB 🔴 +2.02 kB
assets/UserCheckView-BlULk3W_.js (new) 8.8 kB 🔴 +8.8 kB 🔴 +2.22 kB 🔴 +1.93 kB
assets/UserCheckView-Dst0Z7bI.js (removed) 8.8 kB 🟢 -8.8 kB 🟢 -2.22 kB 🟢 -1.93 kB
assets/WidgetTextPreview-BlhMh6hL.js (new) 6.13 kB 🔴 +6.13 kB 🔴 +2.16 kB 🔴 +1.92 kB
assets/WidgetTextPreview-CHhgMb74.js (removed) 6.13 kB 🟢 -6.13 kB 🟢 -2.16 kB 🟢 -1.92 kB
assets/CloudSubscriptionRedirectView-BB-juLj5.js (new) 6.06 kB 🔴 +6.06 kB 🔴 +2.27 kB 🔴 +1.97 kB
assets/CloudSubscriptionRedirectView-Bfo5R5Tc.js (removed) 6.06 kB 🟢 -6.06 kB 🟢 -2.26 kB 🟢 -1.97 kB
assets/UserSelectView-CXZmqDlL.js (new) 5.54 kB 🔴 +5.54 kB 🔴 +1.99 kB 🔴 +1.74 kB
assets/UserSelectView-dIs6e42Z.js (removed) 5.54 kB 🟢 -5.54 kB 🟢 -1.99 kB 🟢 -1.74 kB
assets/CloudForgotPasswordView-BC-CuoiM.js (removed) 5.15 kB 🟢 -5.15 kB 🟢 -1.76 kB 🟢 -1.54 kB
assets/CloudForgotPasswordView-bOf7vVo5.js (new) 5.15 kB 🔴 +5.15 kB 🔴 +1.76 kB 🔴 +1.54 kB
assets/CloudAuthTimeoutView-CmA60WHJ.js (new) 4.49 kB 🔴 +4.49 kB 🔴 +1.57 kB 🔴 +1.37 kB
assets/CloudAuthTimeoutView-Du5JN-wR.js (removed) 4.49 kB 🟢 -4.49 kB 🟢 -1.57 kB 🟢 -1.36 kB
assets/OAuthLayoutView-BAhHWcuy.js (new) 1.36 kB 🔴 +1.36 kB 🔴 +734 B 🔴 +620 B
assets/OAuthLayoutView-DP-HhRs9.js (removed) 1.36 kB 🟢 -1.36 kB 🟢 -734 B 🟢 -620 B
assets/WidgetTextPreview-BGPDoLjj.js (removed) 131 B 🟢 -131 B 🟢 -100 B 🟢 -90 B
assets/WidgetTextPreview-DQK1kRik.js (new) 131 B 🔴 +131 B 🔴 +100 B 🔴 +88 B

Status: 12 added / 12 removed / 4 unchanged

Panels & Settings — 551 kB (baseline 551 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/KeybindingPanel-_uW_Nzbv.js (new) 49.5 kB 🔴 +49.5 kB 🔴 +9.97 kB 🔴 +8.83 kB
assets/KeybindingPanel-BPzfDdVA.js (removed) 49.5 kB 🟢 -49.5 kB 🟢 -9.97 kB 🟢 -8.84 kB
assets/SecretsPanel-Bf-l1y1h.js (new) 31.3 kB 🔴 +31.3 kB 🔴 +7.62 kB 🔴 +6.67 kB
assets/SecretsPanel-Ck4P19uA.js (removed) 31.3 kB 🟢 -31.3 kB 🟢 -7.62 kB 🟢 -6.67 kB
assets/CreditsPanel-BX4SthnO.js (removed) 16 kB 🟢 -16 kB 🟢 -4.66 kB 🟢 -4.09 kB
assets/CreditsPanel-CLhhMMJC.js (new) 16 kB 🔴 +16 kB 🔴 +4.66 kB 🔴 +4.09 kB
assets/SubscriptionPanel-DPwM0l2T.js (removed) 11.5 kB 🟢 -11.5 kB 🟢 -3.65 kB 🟢 -3.21 kB
assets/SubscriptionPanel-sOK_2IZK.js (new) 11.5 kB 🔴 +11.5 kB 🔴 +3.65 kB 🔴 +3.22 kB
assets/AboutPanel-CWkLHCaP.js (removed) 11.2 kB 🟢 -11.2 kB 🟢 -3.06 kB 🟢 -2.74 kB
assets/AboutPanel-DtF-DB8H.js (new) 11.2 kB 🔴 +11.2 kB 🔴 +3.06 kB 🔴 +2.74 kB
assets/ExtensionPanel-Cn5nuljj.js (new) 9.24 kB 🔴 +9.24 kB 🔴 +2.54 kB 🔴 +2.26 kB
assets/ExtensionPanel-eYpAxNmv.js (removed) 9.24 kB 🟢 -9.24 kB 🟢 -2.54 kB 🟢 -2.25 kB
assets/ServerConfigPanel-CBHBgPU2.js (removed) 6.15 kB 🟢 -6.15 kB 🟢 -1.97 kB 🟢 -1.75 kB
assets/ServerConfigPanel-D8CIi_sd.js (new) 6.15 kB 🔴 +6.15 kB 🔴 +1.97 kB 🔴 +1.75 kB
assets/UserPanel-3DLWaAj7.js (removed) 5.78 kB 🟢 -5.78 kB 🟢 -1.81 kB 🟢 -1.57 kB
assets/UserPanel-DOcWpXa-.js (new) 5.78 kB 🔴 +5.78 kB 🔴 +1.81 kB 🔴 +1.57 kB
assets/refreshRemoteConfig-BkB5-qOA.js (removed) 2.97 kB 🟢 -2.97 kB 🟢 -1.27 kB 🟢 -1.11 kB
assets/refreshRemoteConfig-qEOhh5KV.js (new) 2.97 kB 🔴 +2.97 kB 🔴 +1.27 kB 🔴 +1.11 kB
assets/cloudRemoteConfig-C-XyUPop.js (removed) 988 B 🟢 -988 B 🟢 -539 B 🟢 -458 B
assets/cloudRemoteConfig-CpHbRdkR.js (new) 988 B 🔴 +988 B 🔴 +539 B 🔴 +453 B
assets/refreshRemoteConfig-C1Jegrjr.js (removed) 110 B 🟢 -110 B 🟢 -89 B 🟢 -84 B
assets/refreshRemoteConfig-DXMqSy-D.js (new) 110 B 🔴 +110 B 🔴 +89 B 🔴 +82 B

Status: 11 added / 11 removed / 15 unchanged

User & Accounts — 29.1 kB (baseline 29.1 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SignUpForm-CAzsfxh8.js (removed) 12.3 kB 🟢 -12.3 kB 🟢 -4.18 kB 🟢 -3.65 kB
assets/SignUpForm-CbWC-zxM.js (new) 12.3 kB 🔴 +12.3 kB 🔴 +4.18 kB 🔴 +3.65 kB
assets/auth-Cj4nczix.js (new) 3.69 kB 🔴 +3.69 kB 🔴 +1.3 kB 🔴 +1.12 kB
assets/auth-D0d8OIyR.js (removed) 3.69 kB 🟢 -3.69 kB 🟢 -1.3 kB 🟢 -1.12 kB
assets/usePostAuthRedirect-B5ia5BO3.js (removed) 3.33 kB 🟢 -3.33 kB 🟢 -1.27 kB 🟢 -1.11 kB
assets/usePostAuthRedirect-B6SRy-c4.js (new) 3.33 kB 🔴 +3.33 kB 🔴 +1.27 kB 🔴 +1.11 kB
assets/UpdatePasswordContent-D24F3bkX.js (removed) 1.91 kB 🟢 -1.91 kB 🟢 -873 B 🟢 -758 B
assets/UpdatePasswordContent-DkRAdOja.js (new) 1.91 kB 🔴 +1.91 kB 🔴 +871 B 🔴 +760 B
assets/authStore-C--swi7t.js (new) 128 B 🔴 +128 B 🔴 +104 B 🔴 +105 B
assets/authStore-fAObFLn8.js (removed) 128 B 🟢 -128 B 🟢 -104 B 🟢 -106 B
assets/workspaceAuthStore-BzLniGvE.js (new) 108 B 🔴 +108 B 🔴 +99 B 🔴 +110 B
assets/workspaceAuthStore-DNs1Hq3p.js (removed) 108 B 🟢 -108 B 🟢 -99 B 🟢 -106 B
assets/auth-Dv8bMB_A.js (removed) 105 B 🟢 -105 B 🟢 -96 B 🟢 -89 B
assets/auth-OVZPgRsR.js (new) 105 B 🔴 +105 B 🔴 +96 B 🔴 +93 B

Status: 7 added / 7 removed / 3 unchanged

Editors & Dialogs — 121 kB (baseline 121 kB) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyHubPublishDialog-D7JeUeYJ.js (removed) 89.9 kB 🟢 -89.9 kB 🟢 -19.2 kB 🟢 -16.5 kB
assets/ComfyHubPublishDialog-T_KTClX5.js (new) 89.9 kB 🔴 +89.9 kB 🔴 +19.2 kB 🔴 +16.5 kB
assets/useShareDialog-D-mEPEaX.js (new) 23.7 kB 🔴 +23.7 kB 🔴 +5.58 kB 🔴 +4.96 kB
assets/useShareDialog-DMM4G_bu.js (removed) 23.7 kB 🟢 -23.7 kB 🟢 -5.58 kB 🟢 -4.95 kB
assets/feedbackDialog-CdTR_K7m.js (new) 4.5 kB 🔴 +4.5 kB 🔴 +1.9 kB 🔴 +1.62 kB
assets/feedbackDialog-KOGahbKZ.js (removed) 4.5 kB 🟢 -4.5 kB 🟢 -1.9 kB 🟢 -1.62 kB
assets/ComfyHubPublishDialog-Bkh8FSqJ.js (new) 143 B 🔴 +143 B 🔴 +105 B 🔴 +97 B
assets/ComfyHubPublishDialog-CMcEGjsh.js (removed) 143 B 🟢 -143 B 🟢 -105 B 🟢 -90 B
assets/useSubscriptionDialog-BM1o1e4Q.js (new) 108 B 🔴 +108 B 🔴 +102 B 🔴 +91 B
assets/useSubscriptionDialog-v_NXabkm.js (removed) 108 B 🟢 -108 B 🟢 -102 B 🟢 -90 B

Status: 5 added / 5 removed / 1 unchanged

UI Components — 64.8 kB (baseline 64.8 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-D3ii8Te5.js (new) 13.5 kB 🔴 +13.5 kB 🔴 +3.76 kB 🔴 +3.34 kB
assets/ComfyQueueButton-D8hUjdRZ.js (removed) 13.5 kB 🟢 -13.5 kB 🟢 -3.77 kB 🟢 -3.34 kB
assets/useTerminalTabs-CPhwY9Fw.js (removed) 11.8 kB 🟢 -11.8 kB 🟢 -3.72 kB 🟢 -3.29 kB
assets/useTerminalTabs-D_quS18G.js (new) 11.8 kB 🔴 +11.8 kB 🔴 +3.72 kB 🔴 +3.29 kB
assets/InviteMembersForm-CG7iffNM.js (new) 8.02 kB 🔴 +8.02 kB 🔴 +2.68 kB 🔴 +2.38 kB
assets/InviteMembersForm-DgQXsHds.js (removed) 8.02 kB 🟢 -8.02 kB 🟢 -2.68 kB 🟢 -2.4 kB
assets/SubscribeButton-D6r7nu0i.js (new) 2.18 kB 🔴 +2.18 kB 🔴 +987 B 🔴 +861 B
assets/SubscribeButton-uaksogvj.js (removed) 2.18 kB 🟢 -2.18 kB 🟢 -987 B 🟢 -865 B
assets/cloudFeedbackTopbarButton-C5pJoUjh.js (new) 768 B 🔴 +768 B 🔴 +453 B 🔴 +406 B
assets/cloudFeedbackTopbarButton-D5HfyivD.js (removed) 768 B 🟢 -768 B 🟢 -455 B 🟢 -406 B
assets/ComfyQueueButton-DKpX7WQA.js (new) 128 B 🔴 +128 B 🔴 +99 B 🔴 +90 B
assets/ComfyQueueButton-DPe-Awu9.js (removed) 128 B 🟢 -128 B 🟢 -99 B 🟢 -90 B

Status: 6 added / 6 removed / 8 unchanged

Data & Services — 3.42 MB (baseline 3.42 MB) • 🟢 -525 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/settingStore-DJ35jtQK.js (removed) 3.15 MB 🟢 -3.15 MB 🟢 -730 kB 🟢 -550 kB
assets/settingStore-BT8Rz1Qo.js (new) 3.15 MB 🔴 +3.15 MB 🔴 +729 kB 🔴 +550 kB
assets/load3dService-C0crrUEO.js (removed) 132 kB 🟢 -132 kB 🟢 -29.2 kB 🟢 -24.6 kB
assets/load3dService-ND3Tfkcf.js (new) 132 kB 🔴 +132 kB 🔴 +29.3 kB 🔴 +24.6 kB
assets/api-CECiQZ80.js (removed) 91.4 kB 🟢 -91.4 kB 🟢 -25.3 kB 🟢 -21.8 kB
assets/api-NL725qqo.js (new) 91.4 kB 🔴 +91.4 kB 🔴 +25.3 kB 🔴 +21.7 kB
assets/workflowShareService-J0cGF8jz.js (new) 16.5 kB 🔴 +16.5 kB 🔴 +4.93 kB 🔴 +4.36 kB
assets/workflowShareService-JRvZtXJs.js (removed) 16.5 kB 🟢 -16.5 kB 🟢 -4.92 kB 🟢 -4.36 kB
assets/keybindingService-iSSKsz2J.js (removed) 7.28 kB 🟢 -7.28 kB 🟢 -1.9 kB 🟢 -1.62 kB
assets/keybindingService-TsJmdZ6J.js (new) 7.28 kB 🔴 +7.28 kB 🔴 +1.9 kB 🔴 +1.62 kB
assets/releaseStore-BcVO7DgQ.js (new) 6.77 kB 🔴 +6.77 kB 🔴 +2.06 kB 🔴 +1.8 kB
assets/releaseStore-DroGVtU8.js (removed) 6.77 kB 🟢 -6.77 kB 🟢 -2.06 kB 🟢 -1.8 kB
assets/systemStatsStore-BR-9ySNZ.js (new) 4.99 kB 🔴 +4.99 kB 🔴 +1.77 kB 🔴 +1.5 kB
assets/systemStatsStore-BrJbOmX0.js (removed) 4.99 kB 🟢 -4.99 kB 🟢 -1.77 kB 🟢 -1.5 kB
assets/userStore-BwGhValT.js (new) 2.42 kB 🔴 +2.42 kB 🔴 +932 B 🔴 +826 B
assets/userStore-mG0o4vnd.js (removed) 2.42 kB 🟢 -2.42 kB 🟢 -930 B 🟢 -820 B
assets/audioService-B-GUoLFA.js (removed) 1.76 kB 🟢 -1.76 kB 🟢 -863 B 🟢 -748 B
assets/audioService-RN1iiyI9.js (new) 1.76 kB 🔴 +1.76 kB 🔴 +863 B 🔴 +748 B
assets/dialogService-CUWWuIj6.js (new) 98 B 🔴 +98 B 🔴 +97 B 🔴 +83 B
assets/dialogService-HGIyBGxo.js (removed) 98 B 🟢 -98 B 🟢 -97 B 🟢 -81 B
assets/releaseStore-DeRykETP.js (new) 95 B 🔴 +95 B 🔴 +86 B 🔴 +87 B
assets/releaseStore-DfosMmNe.js (removed) 95 B 🟢 -95 B 🟢 -86 B 🟢 -90 B
assets/settingStore-BNulauA8.js (new) 95 B 🔴 +95 B 🔴 +86 B 🔴 +80 B
assets/settingStore-DGhY_TM1.js (removed) 95 B 🟢 -95 B 🟢 -86 B 🟢 -82 B
assets/assetsStore-BLdBVmaK.js (removed) 94 B 🟢 -94 B 🟢 -92 B 🟢 -86 B
assets/assetsStore-DtoZuO-H.js (new) 94 B 🔴 +94 B 🔴 +92 B 🔴 +83 B
assets/api-CK0dEf9D.js (new) 62 B 🔴 +62 B 🔴 +74 B 🔴 +66 B
assets/api-DXrmaTI1.js (removed) 62 B 🟢 -62 B 🟢 -74 B 🟢 -66 B

Status: 14 added / 14 removed / 3 unchanged

Utilities & Hooks — 369 kB (baseline 369 kB) • 🟢 -28 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useConflictDetection-BM91wowP.js (removed) 235 kB 🟢 -235 kB 🟢 -52.5 kB 🟢 -42.7 kB
assets/useConflictDetection-C9AgPEdL.js (new) 235 kB 🔴 +235 kB 🔴 +52.5 kB 🔴 +42.7 kB
assets/useLoad3d-B_kfvwps.js (removed) 25.8 kB 🟢 -25.8 kB 🟢 -5.82 kB 🟢 -5.16 kB
assets/useLoad3d-CN8x8Jx1.js (new) 25.8 kB 🔴 +25.8 kB 🔴 +5.82 kB 🔴 +5.16 kB
assets/useLoad3dViewer-BGaEWqBT.js (new) 21.3 kB 🔴 +21.3 kB 🔴 +5.01 kB 🔴 +4.41 kB
assets/useLoad3dViewer-Hl3Wm2fa.js (removed) 21.3 kB 🟢 -21.3 kB 🟢 -5.01 kB 🟢 -4.38 kB
assets/useImageQuiet-4_4C0gbi.js (removed) 19.1 kB 🟢 -19.1 kB 🟢 -6.16 kB 🟢 -5.3 kB
assets/useImageQuiet-CPvEnwe_.js (new) 19.1 kB 🔴 +19.1 kB 🔴 +6.15 kB 🔴 +5.3 kB
assets/useFeatureFlags-IrrXx1Wp.js (new) 7.26 kB 🔴 +7.26 kB 🔴 +2.17 kB 🔴 +1.84 kB
assets/useFeatureFlags-ypnvA9ok.js (removed) 7.26 kB 🟢 -7.26 kB 🟢 -2.17 kB 🟢 -1.83 kB
assets/useDowngradeToPersonal-BS0QdsYA.js (removed) 5.9 kB 🟢 -5.9 kB 🟢 -1.8 kB 🟢 -1.57 kB
assets/useDowngradeToPersonal-CyiO-8X9.js (new) 5.9 kB 🔴 +5.9 kB 🔴 +1.8 kB 🔴 +1.57 kB
assets/assetPreviewUtil-CZGHKBO8.js (removed) 2.41 kB 🟢 -2.41 kB 🟢 -1.01 kB 🟢 -874 B
assets/assetPreviewUtil-DO3zpu7g.js (new) 2.41 kB 🔴 +2.41 kB 🔴 +1 kB 🔴 +872 B
assets/useUpstreamValue-B_rnSaNI.js (new) 2.04 kB 🔴 +2.04 kB 🔴 +788 B 🔴 +702 B
assets/useUpstreamValue-DQT0dWiT.js (removed) 2.04 kB 🟢 -2.04 kB 🟢 -790 B 🟢 -702 B
assets/useWorkspaceTierLabel-Cn_sYuLB.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -847 B 🟢 -729 B
assets/useWorkspaceTierLabel-D0yAXUVj.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +848 B 🔴 +734 B
assets/subscriptionCheckoutUtil-aIlE-DhS.js (removed) 903 B 🟢 -903 B 🟢 -536 B 🟢 -457 B
assets/subscriptionCheckoutUtil-Dym7bJ8R.js (new) 903 B 🔴 +903 B 🔴 +537 B 🔴 +458 B
assets/useSessionCookie-B23oGWNH.js (new) 746 B 🔴 +746 B 🔴 +392 B 🔴 +339 B
assets/useSessionCookie-BWnPvEyP.js (removed) 746 B 🟢 -746 B 🟢 -391 B 🟢 -338 B
assets/useLoad3d-CKB6ZkW4.js (new) 311 B 🔴 +311 B 🔴 +164 B 🔴 +147 B
assets/useLoad3d-DkEtLanA.js (removed) 311 B 🟢 -311 B 🟢 -162 B 🟢 -147 B
assets/useSessionCookie-BsenT3L1.js (removed) 101 B 🟢 -101 B 🟢 -86 B 🟢 -83 B
assets/useSessionCookie-NmWB6WdC.js (new) 101 B 🔴 +101 B 🔴 +86 B 🔴 +80 B
assets/useFeatureFlags-BK4BqWnF.js (removed) 98 B 🟢 -98 B 🟢 -85 B 🟢 -79 B
assets/useFeatureFlags-CQ-TZ1gv.js (new) 98 B 🔴 +98 B 🔴 +85 B 🔴 +85 B
assets/useLoad3dViewer-8y988Z7G.js (new) 98 B 🔴 +98 B 🔴 +85 B 🔴 +78 B
assets/useLoad3dViewer-Bx9bVOt8.js (removed) 98 B 🟢 -98 B 🟢 -85 B 🟢 -82 B
assets/useCurrentUser-kOJ3nO83.js (new) 94 B 🔴 +94 B 🔴 +95 B 🔴 +87 B
assets/useCurrentUser-reo1Yg9a.js (removed) 94 B 🟢 -94 B 🟢 -95 B 🟢 -92 B

Status: 16 added / 16 removed / 19 unchanged

Vendor & Third-Party — 15.7 MB (baseline 15.7 MB) • ⚪ 0 B

External libraries and shared vendor chunks

Status: 16 unchanged

Other — 12.5 MB (baseline 12.5 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/core-CiZdtwBi.js (removed) 111 kB 🟢 -111 kB 🟢 -28.7 kB 🟢 -24.3 kB
assets/core-DZLMgAzf.js (new) 111 kB 🔴 +111 kB 🔴 +28.7 kB 🔴 +24.3 kB
assets/WidgetSelect-CJSBSLkV.js (removed) 88 kB 🟢 -88 kB 🟢 -20 kB 🟢 -17.1 kB
assets/WidgetSelect-DCJte7zI.js (new) 88 kB 🔴 +88 kB 🔴 +20 kB 🔴 +17.1 kB
assets/Load3D-CljEXows.js (removed) 71.3 kB 🟢 -71.3 kB 🟢 -11.7 kB 🟢 -10 kB
assets/Load3D-hlRNzJP7.js (new) 71.3 kB 🔴 +71.3 kB 🔴 +11.7 kB 🔴 +10 kB
assets/WorkspaceSettingsPanelContent-CVo6PTLb.js (new) 61.6 kB 🔴 +61.6 kB 🔴 +13.2 kB 🔴 +11.5 kB
assets/WorkspaceSettingsPanelContent-DbPCYJe0.js (removed) 61.6 kB 🟢 -61.6 kB 🟢 -13.2 kB 🟢 -11.5 kB
assets/Preview3d-DSC67KS-.js (removed) 50.9 kB 🟢 -50.9 kB 🟢 -8.34 kB 🟢 -7.27 kB
assets/Preview3d-OzRjvKcS.js (new) 50.9 kB 🔴 +50.9 kB 🔴 +8.34 kB 🔴 +7.28 kB
assets/main-CvAAquNk.js (new) 46.7 kB 🔴 +46.7 kB 🔴 +13.8 kB 🔴 +11.9 kB
assets/main-DS-jJnGz.js (removed) 46.7 kB 🟢 -46.7 kB 🟢 -13.8 kB 🟢 -11.9 kB
assets/SubscriptionTransitionPreviewWorkspace-D1KgQsib.js (new) 45.4 kB 🔴 +45.4 kB 🔴 +9.65 kB 🔴 +8.47 kB
assets/SubscriptionTransitionPreviewWorkspace-fx3fOg8I.js (removed) 45.4 kB 🟢 -45.4 kB 🟢 -9.65 kB 🟢 -8.44 kB
assets/SubscriptionRequiredDialogContentUnified-CGlu4Pe9.js (removed) 42.1 kB 🟢 -42.1 kB 🟢 -9.37 kB 🟢 -8.15 kB
assets/SubscriptionRequiredDialogContentUnified-CtFSIHk-.js (new) 42.1 kB 🔴 +42.1 kB 🔴 +9.37 kB 🔴 +8.16 kB
assets/MembersPanelContent-COmCIpuA.js (new) 41.9 kB 🔴 +41.9 kB 🔴 +8.8 kB 🔴 +7.84 kB
assets/MembersPanelContent-oZmc-PSu.js (removed) 41.9 kB 🟢 -41.9 kB 🟢 -8.8 kB 🟢 -7.86 kB
assets/WidgetBoundingBoxes-BZn52eBQ.js (removed) 33.8 kB 🟢 -33.8 kB 🟢 -9.19 kB 🟢 -8.16 kB
assets/WidgetBoundingBoxes-DpXIiCo8.js (new) 33.8 kB 🔴 +33.8 kB 🔴 +9.19 kB 🔴 +8.16 kB
assets/WidgetPainter-BENM8ZFS.js (new) 32.7 kB 🔴 +32.7 kB 🔴 +7.9 kB 🔴 +7.01 kB
assets/WidgetPainter-DZqqoAF4.js (removed) 32.7 kB 🟢 -32.7 kB 🟢 -7.9 kB 🟢 -6.98 kB
assets/Load3dViewerContent-BBeIxXCh.js (removed) 30.8 kB 🟢 -30.8 kB 🟢 -6.29 kB 🟢 -5.46 kB
assets/Load3dViewerContent-DahC085U.js (new) 30.8 kB 🔴 +30.8 kB 🔴 +6.29 kB 🔴 +5.45 kB
assets/SubscriptionPanelContentWorkspace-BFnQxX24.js (removed) 26.3 kB 🟢 -26.3 kB 🟢 -6.12 kB 🟢 -5.38 kB
assets/SubscriptionPanelContentWorkspace-fK-LGFFA.js (new) 26.3 kB 🔴 +26.3 kB 🔴 +6.12 kB 🔴 +5.38 kB
assets/SubscriptionRequiredDialogContentWorkspace-B3hNW67e.js (removed) 24.9 kB 🟢 -24.9 kB 🟢 -5.77 kB 🟢 -5.06 kB
assets/SubscriptionRequiredDialogContentWorkspace-DsaLfw3Y.js (new) 24.9 kB 🔴 +24.9 kB 🔴 +5.77 kB 🔴 +5.07 kB
assets/SubscriptionRequiredDialogContent-CKTD2MQw.js (removed) 24.4 kB 🟢 -24.4 kB 🟢 -6 kB 🟢 -5.29 kB
assets/SubscriptionRequiredDialogContent-CMWUVdd5.js (new) 24.4 kB 🔴 +24.4 kB 🔴 +6 kB 🔴 +5.29 kB
assets/WidgetImageCrop-DpQ8UjTw.js (new) 23.3 kB 🔴 +23.3 kB 🔴 +5.75 kB 🔴 +5.04 kB
assets/WidgetImageCrop-DQin7y8i.js (removed) 23.3 kB 🟢 -23.3 kB 🟢 -5.75 kB 🟢 -5.04 kB
assets/load3d-B9e11ugM.js (new) 22.2 kB 🔴 +22.2 kB 🔴 +5.44 kB 🔴 +4.7 kB
assets/load3d-DfJPpIjZ.js (removed) 22.2 kB 🟢 -22.2 kB 🟢 -5.43 kB 🟢 -4.69 kB
assets/CurrentUserPopoverWorkspace-CadLrFmL.js (removed) 20.5 kB 🟢 -20.5 kB 🟢 -4.71 kB 🟢 -4.18 kB
assets/CurrentUserPopoverWorkspace-CwKkLgAh.js (new) 20.5 kB 🔴 +20.5 kB 🔴 +4.71 kB 🔴 +4.19 kB
assets/SignInContent-Bdc1gPpl.js (removed) 20.3 kB 🟢 -20.3 kB 🟢 -5.13 kB 🟢 -4.49 kB
assets/SignInContent-DlZ6GsS7.js (new) 20.3 kB 🔴 +20.3 kB 🔴 +5.14 kB 🔴 +4.48 kB
assets/WidgetInputNumber-C4pZB-MK.js (new) 19.1 kB 🔴 +19.1 kB 🔴 +4.83 kB 🔴 +4.29 kB
assets/WidgetInputNumber-DUXS5C6W.js (removed) 19.1 kB 🟢 -19.1 kB 🟢 -4.83 kB 🟢 -4.29 kB
assets/CreditsTile-DmbHxRgy.js (new) 17.2 kB 🔴 +17.2 kB 🔴 +4.57 kB 🔴 +4.03 kB
assets/CreditsTile-Dxj0Y6A3.js (removed) 17.2 kB 🟢 -17.2 kB 🟢 -4.57 kB 🟢 -4.03 kB
assets/WidgetRange-7mmo-ViD.js (new) 16.7 kB 🔴 +16.7 kB 🔴 +4.3 kB 🔴 +3.85 kB
assets/WidgetRange-DdwUG31O.js (removed) 16.7 kB 🟢 -16.7 kB 🟢 -4.31 kB 🟢 -3.85 kB
assets/WidgetRecordAudio-B3tNUqeC.js (removed) 16.6 kB 🟢 -16.6 kB 🟢 -4.63 kB 🟢 -4.13 kB
assets/WidgetRecordAudio-x8R2oERX.js (new) 16.6 kB 🔴 +16.6 kB 🔴 +4.63 kB 🔴 +4.13 kB
assets/WaveAudioPlayer-B3G2hhT0.js (removed) 12.8 kB 🟢 -12.8 kB 🟢 -3.5 kB 🟢 -3.06 kB
assets/WaveAudioPlayer-flYIY49I.js (new) 12.8 kB 🔴 +12.8 kB 🔴 +3.5 kB 🔴 +3.06 kB
assets/WidgetCurve-BCOaZRl2.js (removed) 11.3 kB 🟢 -11.3 kB 🟢 -3.51 kB 🟢 -3.16 kB
assets/WidgetCurve-D_8UiCit.js (new) 11.3 kB 🔴 +11.3 kB 🔴 +3.5 kB 🔴 +3.17 kB
assets/TeamWorkspacesDialogContent-Bi6-CICI.js (removed) 10.3 kB 🟢 -10.3 kB 🟢 -3 kB 🟢 -2.66 kB
assets/TeamWorkspacesDialogContent-C25oShe3.js (new) 10.3 kB 🔴 +10.3 kB 🔴 +3 kB 🔴 +2.66 kB
assets/onboardingCloudRoutes-Bo-TybxD.js (new) 9.02 kB 🔴 +9.02 kB 🔴 +2.77 kB 🔴 +2.37 kB
assets/onboardingCloudRoutes-kMFjne1P.js (removed) 9.02 kB 🟢 -9.02 kB 🟢 -2.76 kB 🟢 -2.37 kB
assets/Load3DConfiguration-BZDg4juh.js (removed) 8.97 kB 🟢 -8.97 kB 🟢 -2.64 kB 🟢 -2.33 kB
assets/Load3DConfiguration-ChUKzx1i.js (new) 8.97 kB 🔴 +8.97 kB 🔴 +2.64 kB 🔴 +2.32 kB
assets/SetMemberCreditLimitDialogContent-DGkfUjIY.js (new) 8.54 kB 🔴 +8.54 kB 🔴 +2.37 kB 🔴 +2.07 kB
assets/SetMemberCreditLimitDialogContent-DjJ95UuC.js (removed) 8.54 kB 🟢 -8.54 kB 🟢 -2.37 kB 🟢 -2.08 kB
assets/nodeTemplates-C-vKFr3C.js (new) 8.33 kB 🔴 +8.33 kB 🔴 +2.87 kB 🔴 +2.54 kB
assets/nodeTemplates-DpIZeCUH.js (removed) 8.33 kB 🟢 -8.33 kB 🟢 -2.88 kB 🟢 -2.54 kB
assets/NightlySurveyController-B2GPsaY-.js (new) 7.56 kB 🔴 +7.56 kB 🔴 +2.59 kB 🔴 +2.28 kB
assets/NightlySurveyController-Ce-AKSp7.js (removed) 7.56 kB 🟢 -7.56 kB 🟢 -2.59 kB 🟢 -2.28 kB
assets/WidgetWithControl-0ADrJbb4.js (new) 6.37 kB 🔴 +6.37 kB 🔴 +2.59 kB 🔴 +2.3 kB
assets/WidgetWithControl-BcPu8Za4.js (removed) 6.37 kB 🟢 -6.37 kB 🟢 -2.59 kB 🟢 -2.31 kB
assets/tierBenefits-BVU71NtZ.js (removed) 6.26 kB 🟢 -6.26 kB 🟢 -2 kB 🟢 -1.75 kB
assets/tierBenefits-BwKaTcxq.js (new) 6.26 kB 🔴 +6.26 kB 🔴 +2 kB 🔴 +1.75 kB
assets/CancelSubscriptionDialogContent-7dFHpMu3.js (removed) 5.98 kB 🟢 -5.98 kB 🟢 -2.04 kB 🟢 -1.79 kB
assets/CancelSubscriptionDialogContent-BGWkhrkb.js (new) 5.98 kB 🔴 +5.98 kB 🔴 +2.04 kB 🔴 +1.79 kB
assets/load3dPreviewExtensions-CylALXq2.js (new) 5.94 kB 🔴 +5.94 kB 🔴 +1.85 kB 🔴 +1.62 kB
assets/load3dPreviewExtensions-mCrBBTME.js (removed) 5.94 kB 🟢 -5.94 kB 🟢 -1.84 kB 🟢 -1.62 kB
assets/FreeTierDialogContent-DChenaWE.js (removed) 5.47 kB 🟢 -5.47 kB 🟢 -1.83 kB 🟢 -1.61 kB
assets/FreeTierDialogContent-Kw-8Wp72.js (new) 5.47 kB 🔴 +5.47 kB 🔴 +1.83 kB 🔴 +1.61 kB
assets/CreateWorkspaceDialogContent-DJq03N0i.js (removed) 5.19 kB 🟢 -5.19 kB 🟢 -1.83 kB 🟢 -1.58 kB
assets/CreateWorkspaceDialogContent-M0ENtWZw.js (new) 5.19 kB 🔴 +5.19 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/ChangeMemberRoleDialogContent-DLM5IJOT.js (removed) 5.04 kB 🟢 -5.04 kB 🟢 -1.67 kB 🟢 -1.45 kB
assets/ChangeMemberRoleDialogContent-DMrPM007.js (new) 5.04 kB 🔴 +5.04 kB 🔴 +1.67 kB 🔴 +1.46 kB
assets/missingModelDownload-B57k3xGo.js (removed) 5.03 kB 🟢 -5.03 kB 🟢 -1.96 kB 🟢 -1.7 kB
assets/missingModelDownload-C6-VH3Rb.js (new) 5.03 kB 🔴 +5.03 kB 🔴 +1.95 kB 🔴 +1.7 kB
assets/EditWorkspaceDialogContent-BLV5xeTI.js (removed) 5 kB 🟢 -5 kB 🟢 -1.79 kB 🟢 -1.55 kB
assets/EditWorkspaceDialogContent-DHKc-zlS.js (new) 5 kB 🔴 +5 kB 🔴 +1.79 kB 🔴 +1.55 kB
assets/WidgetTextarea-B0QS_XWY.js (removed) 4.86 kB 🟢 -4.86 kB 🟢 -1.9 kB 🟢 -1.65 kB
assets/WidgetTextarea-o9iS4atT.js (new) 4.86 kB 🔴 +4.86 kB 🔴 +1.9 kB 🔴 +1.66 kB
assets/saveMesh-BDTZkge4.js (removed) 4.81 kB 🟢 -4.81 kB 🟢 -1.55 kB 🟢 -1.37 kB
assets/saveMesh-DIWrFgym.js (new) 4.81 kB 🔴 +4.81 kB 🔴 +1.55 kB 🔴 +1.38 kB
assets/WorkspacePanelContent-C_UO53cA.js (new) 4.78 kB 🔴 +4.78 kB 🔴 +1.63 kB 🔴 +1.43 kB
assets/WorkspacePanelContent-CYWOLdsp.js (removed) 4.78 kB 🟢 -4.78 kB 🟢 -1.64 kB 🟢 -1.43 kB
assets/InviteMemberDialogContent-BKvINRcb.js (new) 4.75 kB 🔴 +4.75 kB 🔴 +1.62 kB 🔴 +1.4 kB
assets/InviteMemberDialogContent-D1exQc70.js (removed) 4.75 kB 🟢 -4.75 kB 🟢 -1.61 kB 🟢 -1.4 kB
assets/ValueControlPopover-1V5bLevU.js (new) 4.54 kB 🔴 +4.54 kB 🔴 +1.58 kB 🔴 +1.42 kB
assets/ValueControlPopover-CNPK4jE0.js (removed) 4.54 kB 🟢 -4.54 kB 🟢 -1.58 kB 🟢 -1.42 kB
assets/DeleteWorkspaceDialogContent-8u_ZOaqX.js (new) 3.91 kB 🔴 +3.91 kB 🔴 +1.47 kB 🔴 +1.26 kB
assets/DeleteWorkspaceDialogContent-D7CT2c1u.js (removed) 3.91 kB 🟢 -3.91 kB 🟢 -1.47 kB 🟢 -1.26 kB
assets/LeaveWorkspaceDialogContent-D515BrP8.js (removed) 3.73 kB 🟢 -3.73 kB 🟢 -1.41 kB 🟢 -1.21 kB
assets/LeaveWorkspaceDialogContent-DalGixS7.js (new) 3.73 kB 🔴 +3.73 kB 🔴 +1.42 kB 🔴 +1.22 kB
assets/RemoveMemberDialogContent-BK7pS83V.js (removed) 3.71 kB 🟢 -3.71 kB 🟢 -1.37 kB 🟢 -1.2 kB
assets/RemoveMemberDialogContent-Dmf9vzDx.js (new) 3.71 kB 🔴 +3.71 kB 🔴 +1.37 kB 🔴 +1.18 kB
assets/RevokeInviteDialogContent-CNCPJtuz.js (removed) 3.62 kB 🟢 -3.62 kB 🟢 -1.38 kB 🟢 -1.2 kB
assets/RevokeInviteDialogContent-D52Jcz9K.js (new) 3.62 kB 🔴 +3.62 kB 🔴 +1.38 kB 🔴 +1.2 kB
assets/InviteMemberUpsellDialogContent-BCgWNSU7.js (new) 3.51 kB 🔴 +3.51 kB 🔴 +1.26 kB 🔴 +1.1 kB
assets/InviteMemberUpsellDialogContent-BhT9on7B.js (removed) 3.51 kB 🟢 -3.51 kB 🟢 -1.26 kB 🟢 -1.1 kB
assets/workspaceCheckoutTelemetry-DNDn3pjy.js (removed) 3.46 kB 🟢 -3.46 kB 🟢 -1.56 kB 🟢 -1.35 kB
assets/workspaceCheckoutTelemetry-DQ4SA0AN.js (new) 3.46 kB 🔴 +3.46 kB 🔴 +1.56 kB 🔴 +1.35 kB
assets/Media3DTop-CAtbQhzc.js (removed) 3.26 kB 🟢 -3.26 kB 🟢 -1.3 kB 🟢 -1.13 kB
assets/Media3DTop-U18duBaD.js (new) 3.26 kB 🔴 +3.26 kB 🔴 +1.29 kB 🔴 +1.13 kB
assets/GlobalToast-C47oyigG.js (new) 3.05 kB 🔴 +3.05 kB 🔴 +1.25 kB 🔴 +1.07 kB
assets/GlobalToast-DwJTjuvG.js (removed) 3.05 kB 🟢 -3.05 kB 🟢 -1.25 kB 🟢 -1.11 kB
assets/load3dAdvanced-O8dgOOub.js (removed) 2.87 kB 🟢 -2.87 kB 🟢 -1.13 kB 🟢 -978 B
assets/load3dAdvanced-pMO1eXgX.js (new) 2.87 kB 🔴 +2.87 kB 🔴 +1.13 kB 🔴 +980 B
assets/SubscribeToRun--mLYpbnJ.js (new) 2.45 kB 🔴 +2.45 kB 🔴 +1.06 kB 🔴 +925 B
assets/SubscribeToRun-DtikH1p0.js (removed) 2.45 kB 🟢 -2.45 kB 🟢 -1.06 kB 🟢 -923 B
assets/MediaImageTop-BVFxTuZO.js (removed) 2 kB 🟢 -2 kB 🟢 -961 B 🟢 -840 B
assets/MediaImageTop-Zk3V1ofI.js (new) 2 kB 🔴 +2 kB 🔴 +958 B 🔴 +825 B
assets/MediaAudioTop-D-Yn3kU9.js (removed) 1.67 kB 🟢 -1.67 kB 🟢 -837 B 🟢 -692 B
assets/MediaAudioTop-DR2lDT_0.js (new) 1.67 kB 🔴 +1.67 kB 🔴 +837 B 🔴 +693 B
assets/CloudRunButtonWrapper-6hfCOESZ.js (removed) 1.11 kB 🟢 -1.11 kB 🟢 -547 B 🟢 -478 B
assets/CloudRunButtonWrapper-Mvt2D3XV.js (new) 1.11 kB 🔴 +1.11 kB 🔴 +547 B 🔴 +473 B
assets/cloudSessionCookie-CfKHkzuJ.js (removed) 989 B 🟢 -989 B 🟢 -465 B 🟢 -420 B
assets/cloudSessionCookie-CGyK_pwt.js (new) 989 B 🔴 +989 B 🔴 +466 B 🔴 +401 B
assets/cloudBadges-BMnpRhG5.js (new) 971 B 🔴 +971 B 🔴 +547 B 🔴 +463 B
assets/cloudBadges-D4avUSYt.js (removed) 971 B 🟢 -971 B 🟢 -548 B 🟢 -462 B
assets/Load3DAdvanced-BezMEaF3.js (removed) 813 B 🟢 -813 B 🟢 -452 B 🟢 -405 B
assets/Load3DAdvanced-DeIgj9bL.js (new) 813 B 🔴 +813 B 🔴 +453 B 🔴 +408 B
assets/nightlyBadges-BL7qZ_cU.js (removed) 462 B 🟢 -462 B 🟢 -306 B 🟢 -251 B
assets/nightlyBadges-n7NTyDYu.js (new) 462 B 🔴 +462 B 🔴 +304 B 🔴 +251 B
assets/missingModelDownload-BJ_4sJ_L.js (removed) 228 B 🟢 -228 B 🟢 -151 B 🟢 -129 B
assets/missingModelDownload-FaoI3D4N.js (new) 228 B 🔴 +228 B 🔴 +151 B 🔴 +133 B
assets/SubscriptionPanelContentWorkspace-CL94zJ4r.js (removed) 179 B 🟢 -179 B 🟢 -117 B 🟢 -96 B
assets/SubscriptionPanelContentWorkspace-CUaR-Z4Y.js (new) 179 B 🔴 +179 B 🔴 +117 B 🔴 +92 B
assets/Load3dViewerContent-DRkfRXVd.js (new) 137 B 🔴 +137 B 🔴 +103 B 🔴 +91 B
assets/Load3dViewerContent-DWpMk3fP.js (removed) 137 B 🟢 -137 B 🟢 -103 B 🟢 -91 B
assets/Load3DAdvanced-BA1ODVHp.js (removed) 122 B 🟢 -122 B 🟢 -97 B 🟢 -81 B
assets/Load3DAdvanced-CGkEQ1L_.js (new) 122 B 🔴 +122 B 🔴 +97 B 🔴 +87 B
assets/WidgetLegacy-BimNFVcW.js (new) 117 B 🔴 +117 B 🔴 +106 B 🔴 +104 B
assets/WidgetLegacy-CA2MhaSw.js (removed) 117 B 🟢 -117 B 🟢 -106 B 🟢 -94 B
assets/workflowDraftStoreV2-B9c6NWBK.js (new) 112 B 🔴 +112 B 🔴 +101 B 🔴 +107 B
assets/workflowDraftStoreV2-M-WRNMhR.js (removed) 112 B 🟢 -112 B 🟢 -101 B 🟢 -108 B
assets/Load3D-CerT4qVi.js (removed) 98 B 🟢 -98 B 🟢 -89 B 🟢 -78 B
assets/Load3D-nkOAo_C5.js (new) 98 B 🔴 +98 B 🔴 +89 B 🔴 +80 B
assets/changeTracker-BHKw4_M3.js (new) 91 B 🔴 +91 B 🔴 +93 B 🔴 +88 B
assets/changeTracker-BPpBC8IX.js (removed) 91 B 🟢 -91 B 🟢 -93 B 🟢 -86 B

Status: 70 added / 70 removed / 207 unchanged

⚡ Performance Report

canvas-idle: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 56.0 MB heap
canvas-mouse-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 48.9 MB heap
canvas-zoom-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 71.7 MB heap
dom-widget-clipping: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 53.2 MB heap
large-graph-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 62.1 MB heap
large-graph-pan: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 60.7 MB heap
large-graph-zoom: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 57.3 MB heap
minimap-idle: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 65.3 MB heap
subgraph-dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 53.6 MB heap
subgraph-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 68.3 MB heap
subgraph-mouse-sweep: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 52.9 MB heap
subgraph-transition-enter: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 130ms TBT · 96.4 MB heap
viewport-pan-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 69.6 MB heap
vue-large-graph-idle: · 56.2 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 3ms TBT · 159.4 MB heap
vue-large-graph-pan: · 56.3 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 116ms TBT · 160.3 MB heap
workflow-execution: · 60.0 avg FPS · 59.7 P5 FPS ✅ (target: ≥52) · 0ms TBT · 48.8 MB heap

⚠️ 5 regressions detected

Show regressions
Metric Baseline PR (median) Δ Sig
canvas-idle: task duration 445ms 504ms +13% ⚠️ z=3.5
large-graph-idle: task duration 608ms 695ms +14% ⚠️ z=2.8
large-graph-pan: task duration 1123ms 1273ms +13% ⚠️ z=4.4
minimap-idle: task duration 612ms 666ms +9% ⚠️ z=2.9
subgraph-idle: task duration 422ms 458ms +8% ⚠️ z=2.8
All metrics
Metric Baseline PR (median) Δ Sig
canvas-idle: avg frame time 17ms 17ms +0% z=0.4
canvas-idle: p95 frame time 17ms 17ms -0%
canvas-idle: layout duration 0ms 0ms +0%
canvas-idle: style recalc duration 6ms 9ms +37% z=-2.6
canvas-idle: layout count 0 0 +0%
canvas-idle: style recalc count 9 10 +6% z=-2.9
canvas-idle: task duration 445ms 504ms +13% ⚠️ z=3.5
canvas-idle: script duration 16ms 16ms +2% z=-4.0
canvas-idle: TBT 0ms 0ms +0%
canvas-idle: heap used 68.0 MB 56.0 MB -18%
canvas-idle: DOM nodes 18 -127 -803% z=-116.9
canvas-idle: event listeners 6 -72 -1300% z=-17.7
canvas-mouse-sweep: avg frame time 17ms 17ms +0% z=-0.4
canvas-mouse-sweep: p95 frame time 17ms 17ms -1%
canvas-mouse-sweep: layout duration 3ms 4ms +22% z=0.6
canvas-mouse-sweep: style recalc duration 33ms 42ms +28% z=-0.1
canvas-mouse-sweep: layout count 12 12 +0%
canvas-mouse-sweep: style recalc count 72 78 +8% z=-0.5
canvas-mouse-sweep: task duration 815ms 941ms +15% z=1.3
canvas-mouse-sweep: script duration 105ms 127ms +21% z=-1.3
canvas-mouse-sweep: TBT 0ms 0ms +0%
canvas-mouse-sweep: heap used 49.9 MB 48.9 MB -2%
canvas-mouse-sweep: DOM nodes -275 -275 +0% z=-130.4
canvas-mouse-sweep: event listeners -148 -148 +0% z=-37.5
canvas-zoom-sweep: avg frame time 17ms 17ms -0% z=-1.1
canvas-zoom-sweep: p95 frame time 17ms 17ms +0%
canvas-zoom-sweep: layout duration 1ms 1ms -12% z=0.4
canvas-zoom-sweep: style recalc duration 15ms 17ms +13% z=-1.5
canvas-zoom-sweep: layout count 6 6 +0%
canvas-zoom-sweep: style recalc count 32 32 +0% z=1.6
canvas-zoom-sweep: task duration 348ms 369ms +6% z=1.8
canvas-zoom-sweep: script duration 18ms 19ms +6% z=-2.6
canvas-zoom-sweep: TBT 0ms 0ms +0%
canvas-zoom-sweep: heap used 71.7 MB 71.7 MB -0%
canvas-zoom-sweep: DOM nodes 76 78 +3% z=-1.6
canvas-zoom-sweep: event listeners 19 19 +0% z=-0.9
dom-widget-clipping: avg frame time 17ms 17ms +0% z=0.1
dom-widget-clipping: p95 frame time 17ms 17ms +0%
dom-widget-clipping: layout duration 0ms 0ms +0%
dom-widget-clipping: style recalc duration 6ms 8ms +24% z=-2.5
dom-widget-clipping: layout count 0 0 +0%
dom-widget-clipping: style recalc count 12 11 -8% z=-4.2
dom-widget-clipping: task duration 340ms 375ms +10% z=0.6
dom-widget-clipping: script duration 49ms 59ms +22% z=-2.6
dom-widget-clipping: TBT 0ms 0ms +0%
dom-widget-clipping: heap used 53.0 MB 53.2 MB +0%
dom-widget-clipping: DOM nodes 20 18 -10% z=-2.9
dom-widget-clipping: event listeners 0 2 variance too high
large-graph-idle: avg frame time 17ms 17ms +0% z=-0.2
large-graph-idle: p95 frame time 17ms 17ms +0%
large-graph-idle: layout duration 0ms 0ms +0%
large-graph-idle: style recalc duration 6ms 8ms +28% z=-3.8
large-graph-idle: layout count 0 0 +0%
large-graph-idle: style recalc count 9 9 -6% z=-9.9
large-graph-idle: task duration 608ms 695ms +14% ⚠️ z=2.8
large-graph-idle: script duration 81ms 114ms +41% z=1.1
large-graph-idle: TBT 0ms 0ms +0%
large-graph-idle: heap used 62.7 MB 62.1 MB -1%
large-graph-idle: DOM nodes -276 -275 -0% z=-331.6
large-graph-idle: event listeners -144 -143 -1% z=-27.7
large-graph-pan: avg frame time 17ms 17ms -0% z=-0.2
large-graph-pan: p95 frame time 17ms 17ms +0%
large-graph-pan: layout duration 0ms 0ms +0%
large-graph-pan: style recalc duration 12ms 14ms +11% z=-4.3
large-graph-pan: layout count 0 0 +0%
large-graph-pan: style recalc count 68 69 +1% z=-0.9
large-graph-pan: task duration 1123ms 1273ms +13% ⚠️ z=4.4
large-graph-pan: script duration 348ms 424ms +22% z=0.8
large-graph-pan: TBT 0ms 0ms +0%
large-graph-pan: heap used 59.8 MB 60.7 MB +2%
large-graph-pan: DOM nodes -277 -278 +0% z=-179.7
large-graph-pan: event listeners -144 -143 -1% z=-178.6
large-graph-zoom: avg frame time 17ms 17ms -0%
large-graph-zoom: p95 frame time 17ms 17ms +0%
large-graph-zoom: layout duration 8ms 7ms -13%
large-graph-zoom: style recalc duration 15ms 14ms -8%
large-graph-zoom: layout count 60 60 +0%
large-graph-zoom: style recalc count 65 65 -1%
large-graph-zoom: task duration 1325ms 1493ms +13%
large-graph-zoom: script duration 424ms 523ms +23%
large-graph-zoom: TBT 0ms 0ms +0%
large-graph-zoom: heap used 57.2 MB 57.3 MB +0%
large-graph-zoom: DOM nodes -279 -282 +1%
large-graph-zoom: event listeners -148 -148 +0%
minimap-idle: avg frame time 17ms 17ms -0% z=0.1
minimap-idle: p95 frame time 17ms 17ms +0%
minimap-idle: layout duration 0ms 0ms +0%
minimap-idle: style recalc duration 6ms 7ms +5% z=-3.7
minimap-idle: layout count 0 0 +0%
minimap-idle: style recalc count 9 8 -17% z=-3.0
minimap-idle: task duration 612ms 666ms +9% ⚠️ z=2.9
minimap-idle: script duration 79ms 106ms +34% z=0.8
minimap-idle: TBT 0ms 0ms +0%
minimap-idle: heap used 63.9 MB 65.3 MB +2%
minimap-idle: DOM nodes -276 -275 -0% z=-215.1
minimap-idle: event listeners -144 -144 +0% z=-225.0
subgraph-dom-widget-clipping: avg frame time 17ms 17ms +0% z=0.7
subgraph-dom-widget-clipping: p95 frame time 17ms 17ms +0%
subgraph-dom-widget-clipping: layout duration 0ms 0ms +0%
subgraph-dom-widget-clipping: style recalc duration 10ms 11ms +6% z=-2.1
subgraph-dom-widget-clipping: layout count 0 0 +0%
subgraph-dom-widget-clipping: style recalc count 48 48 +0% z=0.1
subgraph-dom-widget-clipping: task duration 377ms 394ms +5% z=0.9
subgraph-dom-widget-clipping: script duration 110ms 115ms +5% z=-2.0
subgraph-dom-widget-clipping: TBT 0ms 0ms +0%
subgraph-dom-widget-clipping: heap used 53.6 MB 53.6 MB -0%
subgraph-dom-widget-clipping: DOM nodes 22 22 +0% z=-0.2
subgraph-dom-widget-clipping: event listeners 6 6 +0% z=-1.7
subgraph-idle: avg frame time 17ms 17ms +0% z=0.4
subgraph-idle: p95 frame time 17ms 17ms -1%
subgraph-idle: layout duration 0ms 0ms +0%
subgraph-idle: style recalc duration 7ms 8ms +13% z=-3.2
subgraph-idle: layout count 0 0 +0%
subgraph-idle: style recalc count 11 10 -14% z=-2.1
subgraph-idle: task duration 422ms 458ms +8% ⚠️ z=2.8
subgraph-idle: script duration 14ms 14ms -2% z=-2.4
subgraph-idle: TBT 0ms 0ms +0%
subgraph-idle: heap used 68.2 MB 68.3 MB +0%
subgraph-idle: DOM nodes 22 19 -14% z=-1.9
subgraph-idle: event listeners 4 4 +0% variance too high
subgraph-mouse-sweep: avg frame time 17ms 17ms +0% z=0.4
subgraph-mouse-sweep: p95 frame time 17ms 17ms +0%
subgraph-mouse-sweep: layout duration 4ms 4ms -6% z=-2.7
subgraph-mouse-sweep: style recalc duration 33ms 35ms +7% z=-2.1
subgraph-mouse-sweep: layout count 16 16 +0%
subgraph-mouse-sweep: style recalc count 76 77 +1% z=-1.9
subgraph-mouse-sweep: task duration 714ms 762ms +7% z=-0.1
subgraph-mouse-sweep: script duration 76ms 89ms +17% z=-1.9
subgraph-mouse-sweep: TBT 0ms 0ms +0%
subgraph-mouse-sweep: heap used 59.5 MB 52.9 MB -11%
subgraph-mouse-sweep: DOM nodes 61 -104 -270% z=-76.3
subgraph-mouse-sweep: event listeners 4 -72 -1900% variance too high
subgraph-transition-enter: avg frame time 17ms 17ms +0%
subgraph-transition-enter: p95 frame time 17ms 17ms +1%
subgraph-transition-enter: layout duration 10ms 13ms +29%
subgraph-transition-enter: style recalc duration 26ms 31ms +17%
subgraph-transition-enter: layout count 15 15 +0%
subgraph-transition-enter: style recalc count 19 19 +0%
subgraph-transition-enter: task duration 830ms 995ms +20%
subgraph-transition-enter: script duration 31ms 37ms +19%
subgraph-transition-enter: TBT 118ms 130ms +10%
subgraph-transition-enter: heap used 92.4 MB 96.4 MB +4%
subgraph-transition-enter: DOM nodes 13673 13673 +0%
subgraph-transition-enter: event listeners 2369 2371 +0%
viewport-pan-sweep: avg frame time 17ms 17ms -0%
viewport-pan-sweep: p95 frame time 17ms 17ms +0%
viewport-pan-sweep: layout duration 0ms 0ms +0%
viewport-pan-sweep: style recalc duration 39ms 38ms -3%
viewport-pan-sweep: layout count 0 0 +0%
viewport-pan-sweep: style recalc count 249 251 +1%
viewport-pan-sweep: task duration 3996ms 4496ms +13%
viewport-pan-sweep: script duration 1161ms 1389ms +20%
viewport-pan-sweep: TBT 0ms 0ms +0%
viewport-pan-sweep: heap used 66.0 MB 69.6 MB +5%
viewport-pan-sweep: DOM nodes -276 -275 -1%
viewport-pan-sweep: event listeners -128 -143 +12%
vue-large-graph-idle: avg frame time 17ms 18ms +3%
vue-large-graph-idle: p95 frame time 17ms 17ms -0%
vue-large-graph-idle: layout duration 0ms 0ms +0%
vue-large-graph-idle: style recalc duration 0ms 0ms +0%
vue-large-graph-idle: layout count 0 0 +0%
vue-large-graph-idle: style recalc count 0 0 +0%
vue-large-graph-idle: task duration 13916ms 16833ms +21%
vue-large-graph-idle: script duration 504ms 568ms +13%
vue-large-graph-idle: TBT 0ms 3ms
vue-large-graph-idle: heap used 158.2 MB 159.4 MB +1%
vue-large-graph-idle: DOM nodes -8312 -8312 +0%
vue-large-graph-idle: event listeners -16389 -16386 -0%
vue-large-graph-pan: avg frame time 17ms 18ms +3%
vue-large-graph-pan: p95 frame time 17ms 17ms -0%
vue-large-graph-pan: layout duration 0ms 0ms +0%
vue-large-graph-pan: style recalc duration 17ms 16ms -5%
vue-large-graph-pan: layout count 0 0 +0%
vue-large-graph-pan: style recalc count 115 136 +18%
vue-large-graph-pan: task duration 17149ms 20178ms +18%
vue-large-graph-pan: script duration 829ms 864ms +4%
vue-large-graph-pan: TBT 20ms 116ms +480%
vue-large-graph-pan: heap used 159.5 MB 160.3 MB +1%
vue-large-graph-pan: DOM nodes -8312 -8312 +0%
vue-large-graph-pan: event listeners -16383 -16382 -0%
workflow-execution: avg frame time 17ms 17ms -0% z=0.1
workflow-execution: p95 frame time 17ms 17ms -0%
workflow-execution: layout duration 1ms 0ms -36% z=-8.3
workflow-execution: style recalc duration 15ms 19ms +22% z=-2.5
workflow-execution: layout count 3 2 -33% z=-5.4
workflow-execution: style recalc count 13 14 +4% z=-2.1
workflow-execution: task duration 107ms 111ms +4% z=-1.1
workflow-execution: script duration 9ms 10ms +12% z=-6.5
workflow-execution: TBT 0ms 0ms +0%
workflow-execution: heap used 48.8 MB 48.8 MB +0%
workflow-execution: DOM nodes 121 125 +3% z=-5.1
workflow-execution: event listeners 65 66 +2% z=3.2
Historical variance (last 15 runs)
Metric μ σ CV
canvas-idle: avg frame time 17ms 0ms 0.0%
canvas-idle: layout duration 0ms 0ms 0.0%
canvas-idle: style recalc duration 11ms 1ms 8.2%
canvas-idle: layout count 0 0 0.0%
canvas-idle: style recalc count 11 1 5.0%
canvas-idle: task duration 395ms 31ms 7.9%
canvas-idle: script duration 25ms 2ms 8.8%
canvas-idle: TBT 0ms 0ms 0.0%
canvas-idle: DOM nodes 23 1 5.6%
canvas-idle: event listeners 12 5 40.9%
canvas-mouse-sweep: avg frame time 17ms 0ms 0.0%
canvas-mouse-sweep: layout duration 4ms 0ms 5.4%
canvas-mouse-sweep: style recalc duration 43ms 3ms 7.4%
canvas-mouse-sweep: layout count 12 0 0.0%
canvas-mouse-sweep: style recalc count 79 2 3.0%
canvas-mouse-sweep: task duration 865ms 58ms 6.7%
canvas-mouse-sweep: script duration 136ms 6ms 4.8%
canvas-mouse-sweep: TBT 0ms 0ms 0.0%
canvas-mouse-sweep: DOM nodes 62 3 4.2%
canvas-mouse-sweep: event listeners 8 4 49.4%
canvas-zoom-sweep: avg frame time 17ms 0ms 0.0%
canvas-zoom-sweep: layout duration 1ms 0ms 7.0%
canvas-zoom-sweep: style recalc duration 19ms 2ms 8.0%
canvas-zoom-sweep: layout count 6 0 0.0%
canvas-zoom-sweep: style recalc count 31 0 1.5%
canvas-zoom-sweep: task duration 327ms 23ms 7.1%
canvas-zoom-sweep: script duration 27ms 3ms 11.1%
canvas-zoom-sweep: TBT 0ms 0ms 0.0%
canvas-zoom-sweep: DOM nodes 79 1 1.0%
canvas-zoom-sweep: event listeners 24 5 21.8%
dom-widget-clipping: avg frame time 17ms 0ms 0.0%
dom-widget-clipping: layout duration 0ms 0ms 0.0%
dom-widget-clipping: style recalc duration 10ms 1ms 8.0%
dom-widget-clipping: layout count 0 0 0.0%
dom-widget-clipping: style recalc count 13 0 3.8%
dom-widget-clipping: task duration 365ms 16ms 4.5%
dom-widget-clipping: script duration 68ms 3ms 4.8%
dom-widget-clipping: TBT 0ms 0ms 0.0%
dom-widget-clipping: DOM nodes 22 1 6.4%
dom-widget-clipping: event listeners 8 6 81.2%
large-graph-idle: avg frame time 17ms 0ms 0.0%
large-graph-idle: layout duration 0ms 0ms 0.0%
large-graph-idle: style recalc duration 12ms 1ms 8.6%
large-graph-idle: layout count 0 0 0.0%
large-graph-idle: style recalc count 12 0 2.7%
large-graph-idle: task duration 542ms 54ms 10.0%
large-graph-idle: script duration 102ms 11ms 10.3%
large-graph-idle: TBT 0ms 0ms 0.0%
large-graph-idle: DOM nodes 25 1 3.7%
large-graph-idle: event listeners 26 6 23.2%
large-graph-pan: avg frame time 17ms 0ms 0.0%
large-graph-pan: layout duration 0ms 0ms 0.0%
large-graph-pan: style recalc duration 17ms 1ms 4.6%
large-graph-pan: layout count 0 0 0.0%
large-graph-pan: style recalc count 70 1 0.9%
large-graph-pan: task duration 1082ms 43ms 4.0%
large-graph-pan: script duration 408ms 20ms 4.8%
large-graph-pan: TBT 0ms 0ms 0.0%
large-graph-pan: DOM nodes 19 2 8.7%
large-graph-pan: event listeners 5 1 16.8%
minimap-idle: avg frame time 17ms 0ms 0.0%
minimap-idle: layout duration 0ms 0ms 0.0%
minimap-idle: style recalc duration 10ms 1ms 8.6%
minimap-idle: layout count 0 0 0.0%
minimap-idle: style recalc count 10 1 7.1%
minimap-idle: task duration 527ms 47ms 9.0%
minimap-idle: script duration 98ms 10ms 10.1%
minimap-idle: TBT 0ms 0ms 0.0%
minimap-idle: DOM nodes 19 1 7.1%
minimap-idle: event listeners 5 1 14.4%
subgraph-dom-widget-clipping: avg frame time 17ms 0ms 0.0%
subgraph-dom-widget-clipping: layout duration 0ms 0ms 0.0%
subgraph-dom-widget-clipping: style recalc duration 13ms 1ms 7.4%
subgraph-dom-widget-clipping: layout count 0 0 0.0%
subgraph-dom-widget-clipping: style recalc count 48 1 1.2%
subgraph-dom-widget-clipping: task duration 378ms 18ms 4.9%
subgraph-dom-widget-clipping: script duration 128ms 6ms 4.9%
subgraph-dom-widget-clipping: TBT 0ms 0ms 0.0%
subgraph-dom-widget-clipping: DOM nodes 22 1 5.0%
subgraph-dom-widget-clipping: event listeners 16 6 36.0%
subgraph-idle: avg frame time 17ms 0ms 0.0%
subgraph-idle: layout duration 0ms 0ms 0.0%
subgraph-idle: style recalc duration 10ms 1ms 7.5%
subgraph-idle: layout count 0 0 0.0%
subgraph-idle: style recalc count 11 1 6.0%
subgraph-idle: task duration 370ms 31ms 8.5%
subgraph-idle: script duration 20ms 3ms 13.2%
subgraph-idle: TBT 0ms 0ms 0.0%
subgraph-idle: DOM nodes 22 1 6.9%
subgraph-idle: event listeners 10 7 64.5%
subgraph-mouse-sweep: avg frame time 17ms 0ms 0.0%
subgraph-mouse-sweep: layout duration 5ms 0ms 6.8%
subgraph-mouse-sweep: style recalc duration 42ms 3ms 7.8%
subgraph-mouse-sweep: layout count 16 0 0.0%
subgraph-mouse-sweep: style recalc count 80 2 2.4%
subgraph-mouse-sweep: task duration 766ms 69ms 9.0%
subgraph-mouse-sweep: script duration 101ms 7ms 6.5%
subgraph-mouse-sweep: TBT 0ms 0ms 0.0%
subgraph-mouse-sweep: DOM nodes 67 2 3.3%
subgraph-mouse-sweep: event listeners 8 4 52.6%
workflow-execution: avg frame time 17ms 0ms 0.0%
workflow-execution: layout duration 2ms 0ms 9.4%
workflow-execution: style recalc duration 24ms 2ms 9.1%
workflow-execution: layout count 5 1 11.0%
workflow-execution: style recalc count 18 2 11.5%
workflow-execution: task duration 123ms 11ms 8.8%
workflow-execution: script duration 29ms 3ms 10.2%
workflow-execution: TBT 0ms 0ms 0.0%
workflow-execution: DOM nodes 161 7 4.4%
workflow-execution: event listeners 52 4 8.4%
Trend (last 15 commits on main)
Metric Trend Dir Latest
canvas-idle: avg frame time ▆▃▆▁▆▃▆█▆▆▄▃▃▄▃ ➡️ 17ms
canvas-idle: p95 frame time ➡️ NaNms
canvas-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-idle: style recalc duration ▇▇▆▆▃█▄▃▄▃▇▄▁▆▇ ➡️ 11ms
canvas-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
canvas-idle: style recalc count █▃▅▂▅▆▃▁▂▁▂▅▆▅▆ ➡️ 12
canvas-idle: task duration ▃▃▃▆▂▃▃▅▆▂█▃▁▃▃ ➡️ 391ms
canvas-idle: script duration ▄▃▅▇▂▅▃▆▇▅█▄▁▅▆ ➡️ 27ms
canvas-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-idle: heap used ➡️ NaN MB
canvas-idle: DOM nodes █▇▆▅▃▇▃▁▂▂▅▆▆▆▇ ➡️ 24
canvas-idle: event listeners ▅█▅▄▁▅▁▁▁▄▅▅▁▅▄ 📉 11
canvas-mouse-sweep: avg frame time ▆█▆▃▁▃▁▆▆▁▃▆▆▃▃ ➡️ 17ms
canvas-mouse-sweep: p95 frame time ➡️ NaNms
canvas-mouse-sweep: layout duration ▁▃▂▄▁▂▁▃▆▂█▇▆▄▃ ➡️ 4ms
canvas-mouse-sweep: style recalc duration ▄▄▂▄▁▂▃▃▅▄█▆▂▄▄ ➡️ 43ms
canvas-mouse-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 12
canvas-mouse-sweep: style recalc count █▅▄▃▂▂▁▄▄▅▆▅▂▇▄ ➡️ 79
canvas-mouse-sweep: task duration █▆▄▂▂▃▂▄▄▅█▆▁▆▄ ➡️ 868ms
canvas-mouse-sweep: script duration ▄▅▄▆▄▆▆▆▅▅█▆▁▅▆ ➡️ 139ms
canvas-mouse-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-mouse-sweep: heap used ➡️ NaN MB
canvas-mouse-sweep: DOM nodes █▅▃▃▁▂▂▃▂▄▆▅▃▅▅ ➡️ 64
canvas-mouse-sweep: event listeners █▁▁▁▁▁▇▁▁▁██▇▁█ 📈 13
canvas-zoom-sweep: avg frame time ▅▅█▄▅▁▁▁▅▁▁▅▄▅▁ ➡️ 17ms
canvas-zoom-sweep: p95 frame time ➡️ NaNms
canvas-zoom-sweep: layout duration ▆▅▅▄▁▁█▅▃▅▇▆▁▂▆ ➡️ 1ms
canvas-zoom-sweep: style recalc duration ▆▅▄▆▅▃█▆▇▅▇▄▁▃▅ ➡️ 20ms
canvas-zoom-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 6
canvas-zoom-sweep: style recalc count ▁▁▃▄▆▃▆█▄▄▆▁▆▁▆ ➡️ 32
canvas-zoom-sweep: task duration ▄▂▁▇▂▂▄▅▆▃█▄▁▁▅ ➡️ 338ms
canvas-zoom-sweep: script duration ▃▃▂▇▂▂▅▇▆▅█▄▁▂▆ ➡️ 30ms
canvas-zoom-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-zoom-sweep: heap used ➡️ NaN MB
canvas-zoom-sweep: DOM nodes ▄▃▁▅█▁▃▆▄▅▅▃▃▄▃ ➡️ 79
canvas-zoom-sweep: event listeners ▁▁▂▅█▂▁▅▁▅▅▄▁▅▁ ➡️ 19
dom-widget-clipping: avg frame time ▂▄▅▅▂▄█▇▅▇▇▅▅▁▇ ➡️ 17ms
dom-widget-clipping: p95 frame time ➡️ NaNms
dom-widget-clipping: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
dom-widget-clipping: style recalc duration ▆▆▂▆▄▃██▄▁▆▇▆▃▅ ➡️ 10ms
dom-widget-clipping: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
dom-widget-clipping: style recalc count ▇█▅█▅▄█▇▇▁▇▄▇▂▅ ➡️ 13
dom-widget-clipping: task duration ▃▃▁▅▄▃▅▆▅▂▇█▁▅▅ ➡️ 371ms
dom-widget-clipping: script duration ▅▄▄▆▆▅▇▇▆▃█▇▁▇▇ ➡️ 71ms
dom-widget-clipping: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
dom-widget-clipping: heap used ➡️ NaN MB
dom-widget-clipping: DOM nodes ▇▇▄▇▅▄█▇▅▁▅▄▇▃▄ ➡️ 21
dom-widget-clipping: event listeners ▅▅▅▅▁▅██▁▁▁▁█▁▁ 📉 2
large-graph-idle: avg frame time ▅▅▅▅▅▂▁▂▄▅▄▂▂▅█ ➡️ 17ms
large-graph-idle: p95 frame time ➡️ NaNms
large-graph-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-idle: style recalc duration ▅▅▅▆▄▅▃▄▅▅▆█▁▄▆ ➡️ 13ms
large-graph-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
large-graph-idle: style recalc count █▆█▃▃▁▃▆▃▆▆▃▆██ ➡️ 12
large-graph-idle: task duration ▂▃▂▆▂▃▃▇▅▃██▁▂▅ ➡️ 569ms
large-graph-idle: script duration ▄▅▄▆▄▅▅▇▆▅█▆▁▃▆ ➡️ 110ms
large-graph-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-idle: heap used ➡️ NaN MB
large-graph-idle: DOM nodes ▆█▅▂▅▃▁▂▃▅▅▆▂▆▅ ➡️ 25
large-graph-idle: event listeners ███▇██▄▁▄▇▇█▂█▇ ➡️ 29
large-graph-pan: avg frame time ▆▃▃▆█▃▁█▆▆▆▆█▁▆ ➡️ 17ms
large-graph-pan: p95 frame time ➡️ NaNms
large-graph-pan: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-pan: style recalc duration ▃▂▄▄▁▅▂▂▁▄▄█▃▁▂ ➡️ 17ms
large-graph-pan: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
large-graph-pan: style recalc count ▆▃█▂▃▂▂▂▁▇▅▃█▆▃ ➡️ 69
large-graph-pan: task duration ▄▃▄▆▄▄▄▆▄▄█▆▁▂▅ ➡️ 1100ms
large-graph-pan: script duration ▅▄▅▆▆▅▄▆▄▅█▄▁▄▅ ➡️ 413ms
large-graph-pan: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-pan: heap used ➡️ NaN MB
large-graph-pan: DOM nodes ▅▃▆▂▄▁▃▁▁▅▁▂█▅▂ ➡️ 18
large-graph-pan: event listeners █▆█▁▁▆▁▁▃▆▁▃██▃ ➡️ 5
minimap-idle: avg frame time ▃▆▆▃█▁█▆▆▃▃▆█▆█ ➡️ 17ms
minimap-idle: p95 frame time ➡️ NaNms
minimap-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
minimap-idle: style recalc duration ▄█▁█▅▅█▅▅▃▅▁▁▄▆ ➡️ 10ms
minimap-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
minimap-idle: style recalc count ▃▅▂▄█▃▆▁▂▅▂▁▅▆▃ ➡️ 9
minimap-idle: task duration ▃▄▁▅▁▃▄▅▇▃█▅▁▁▅ ➡️ 547ms
minimap-idle: script duration ▄▆▃▇▃▅▆▆▇▅█▅▁▃▆ ➡️ 106ms
minimap-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
minimap-idle: heap used ➡️ NaN MB
minimap-idle: DOM nodes ▃▅▂▄█▃▆▁▂▅▂▁▅▆▃ ➡️ 19
minimap-idle: event listeners ▃▃▆▁▁▁▃▁▁▆▁▃█▆▁ ➡️ 4
subgraph-dom-widget-clipping: avg frame time ▅▄▄▄▄▄█▄▄▄▃▁▆▃▃ ➡️ 17ms
subgraph-dom-widget-clipping: p95 frame time ➡️ NaNms
subgraph-dom-widget-clipping: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-dom-widget-clipping: style recalc duration ▂▄▃▅▅▃▂▅▇▃▄█▁▄▆ ➡️ 14ms
subgraph-dom-widget-clipping: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
subgraph-dom-widget-clipping: style recalc count ▇█▆▃▆▃▁▆█▇▃▆▇█▅ ➡️ 48
subgraph-dom-widget-clipping: task duration ▂▃▃▆▅▅▂▅█▂▆█▁▂▇ ➡️ 398ms
subgraph-dom-widget-clipping: script duration ▃▃▃▄▅▅▂▄█▂▅▇▁▂▅ ➡️ 131ms
subgraph-dom-widget-clipping: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-dom-widget-clipping: heap used ➡️ NaN MB
subgraph-dom-widget-clipping: DOM nodes ▅▇▅▂▅▂▁▅▅▅▁▇▅█▄ ➡️ 22
subgraph-dom-widget-clipping: event listeners ▅▅▅▂▅▁▅██▁▁█▅█▅ 📈 16
subgraph-idle: avg frame time ▆▆█▁▆▃▆▆▆▃▆▁▃▆█ ➡️ 17ms
subgraph-idle: p95 frame time ➡️ NaNms
subgraph-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-idle: style recalc duration ▁▇▃▆▂▄▂▃▃▆▆▄▃▇█ ➡️ 12ms
subgraph-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
subgraph-idle: style recalc count ▃▆▃▃▂▅▁▂▁▆▃▃██▇ ➡️ 12
subgraph-idle: task duration ▁▃▁▇▁▁▃▆▅▂█▅▁▁▄ ➡️ 378ms
subgraph-idle: script duration ▁▃▂▇▁▂▃▇▆▂█▅▂▁▅ ➡️ 22ms
subgraph-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-idle: heap used ➡️ NaN MB
subgraph-idle: DOM nodes ▃▅▃▂▁▄▁▂▁▅▃▂▇█▇ ➡️ 24
subgraph-idle: event listeners ▁▅▁▁▁▁▁▁▁▅▄▁███ 📈 21
subgraph-mouse-sweep: avg frame time ▅▄▁▃▃▄▆▄▆▃▃█▁▃▃ ➡️ 17ms
subgraph-mouse-sweep: p95 frame time ➡️ NaNms
subgraph-mouse-sweep: layout duration ▁▄▄▄▃▃▅▅▅▂█▇▂▃▆ ➡️ 5ms
subgraph-mouse-sweep: style recalc duration ▃▂▄▅▂▃▄▅█▃█▆▁▂▅ ➡️ 43ms
subgraph-mouse-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 16
subgraph-mouse-sweep: style recalc count ▅▂▅▅▁▄▃▅█▅▆▄▂▄▅ ➡️ 81
subgraph-mouse-sweep: task duration ▃▂▄▅▂▄▄▅▇▄█▆▁▃▅ ➡️ 785ms
subgraph-mouse-sweep: script duration ▄▅▄▇▅▅▆▇▆▅██▁▄▆ ➡️ 105ms
subgraph-mouse-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-mouse-sweep: heap used ➡️ NaN MB
subgraph-mouse-sweep: DOM nodes ▅▁▄▅▁▄▃▃█▅▅▄▂▅▃ ➡️ 66
subgraph-mouse-sweep: event listeners ▇▁▂▇▁▂▂▂█▇▂▂▇▇▂ 📈 5
workflow-execution: avg frame time ▆▆▆▄▆▆▃▄▁▄█▆▅▄▆ ➡️ 17ms
workflow-execution: p95 frame time ➡️ NaNms
workflow-execution: layout duration ▁▆▁▃▂▄▃▂▃▃▅█▄▂▅ ➡️ 2ms
workflow-execution: style recalc duration ▃▇▅▇▁▅▆▇█▁██▂▄▆ ➡️ 25ms
workflow-execution: layout count ▁█▂▃▂▃▃▁▃▃▄▃▂▃▂ ➡️ 5
workflow-execution: style recalc count ▃█▅▇▁▄▅▆▅▅▅▅▄▄▂ ➡️ 15
workflow-execution: task duration ▂▅▄▅▁▄▆▆▆▁▇█▁▃▃ ➡️ 120ms
workflow-execution: script duration ▄▃▄▄▃▅▄▅▆▂▇█▁▃▄ ➡️ 29ms
workflow-execution: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
workflow-execution: heap used ➡️ NaN MB
workflow-execution: DOM nodes ▂█▃▆▁▄▃▅▃█▃▃▄▃▁ ➡️ 152
workflow-execution: event listeners ▅███▁▅███▁██▅█▅ ➡️ 49
Raw data
{
  "timestamp": "2026-07-29T02:07:46.112Z",
  "gitSha": "e8d08005a210d3c86e7c881a9eaa960f756a1455",
  "branch": "fix/assets-bare-tag-model-type-fallback",
  "measurements": [
    {
      "name": "canvas-idle",
      "durationMs": 2084.935999999999,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 8.214,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 517.808,
      "heapDeltaBytes": 3584188,
      "heapUsedBytes": 71561536,
      "domNodes": 18,
      "jsHeapTotalBytes": 20312064,
      "scriptDurationMs": 17.616,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-idle",
      "durationMs": 2036.1649999999827,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 8.883000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 490.059,
      "heapDeltaBytes": -22105320,
      "heapUsedBytes": 45804328,
      "domNodes": -271,
      "jsHeapTotalBytes": 20176896,
      "scriptDurationMs": 14.93,
      "eventListeners": -148,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66999999999998,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 2030.0860000000114,
      "styleRecalcs": 79,
      "styleRecalcDurationMs": 45.969,
      "layouts": 12,
      "layoutDurationMs": 3.6929999999999996,
      "taskDurationMs": 1000.1630000000001,
      "heapDeltaBytes": -17445392,
      "heapUsedBytes": 50449756,
      "domNodes": -275,
      "jsHeapTotalBytes": 21749760,
      "scriptDurationMs": 130.416,
      "eventListeners": -148,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1840.9350000000018,
      "styleRecalcs": 76,
      "styleRecalcDurationMs": 38.82,
      "layouts": 12,
      "layoutDurationMs": 3.764,
      "taskDurationMs": 881.857,
      "heapDeltaBytes": -15868460,
      "heapUsedBytes": 52080500,
      "domNodes": -275,
      "jsHeapTotalBytes": 20176896,
      "scriptDurationMs": 123.73299999999998,
      "eventListeners": -148,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1707.505000000026,
      "styleRecalcs": 32,
      "styleRecalcDurationMs": 16.161,
      "layouts": 6,
      "layoutDurationMs": 0.63,
      "taskDurationMs": 365.00600000000003,
      "heapDeltaBytes": 7245772,
      "heapUsedBytes": 75158048,
      "domNodes": 79,
      "jsHeapTotalBytes": 20049920,
      "scriptDurationMs": 17.781,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1739.180000000033,
      "styleRecalcs": 32,
      "styleRecalcDurationMs": 17.575,
      "layouts": 6,
      "layoutDurationMs": 0.6949999999999998,
      "taskDurationMs": 372.66200000000003,
      "heapDeltaBytes": 7246072,
      "heapUsedBytes": 75172992,
      "domNodes": 77,
      "jsHeapTotalBytes": 20312064,
      "scriptDurationMs": 21.135999999999996,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 594.7680000000162,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 8.641,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 376.609,
      "heapDeltaBytes": -12075916,
      "heapUsedBytes": 55819516,
      "domNodes": 18,
      "jsHeapTotalBytes": 20836352,
      "scriptDurationMs": 61.323,
      "eventListeners": 2,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 568.6820000000239,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 7.146000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 373.205,
      "heapDeltaBytes": -12136620,
      "heapUsedBytes": 55844816,
      "domNodes": 18,
      "jsHeapTotalBytes": 20836352,
      "scriptDurationMs": 57.599000000000004,
      "eventListeners": 2,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2023.2469999999694,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 8.043000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 730.998,
      "heapDeltaBytes": 5625508,
      "heapUsedBytes": 64629928,
      "domNodes": -276,
      "jsHeapTotalBytes": 4255744,
      "scriptDurationMs": 124.71099999999998,
      "eventListeners": -142,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2040.862000000061,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 8.548999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 659.403,
      "heapDeltaBytes": 6729076,
      "heapUsedBytes": 65563860,
      "domNodes": -274,
      "jsHeapTotalBytes": 3731456,
      "scriptDurationMs": 102.94,
      "eventListeners": -144,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2177.7819999999792,
      "styleRecalcs": 70,
      "styleRecalcDurationMs": 14.249999999999995,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1243.039,
      "heapDeltaBytes": 5152372,
      "heapUsedBytes": 65259160,
      "domNodes": -278,
      "jsHeapTotalBytes": 4722688,
      "scriptDurationMs": 419.209,
      "eventListeners": -142,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2135.6799999999794,
      "styleRecalcs": 68,
      "styleRecalcDurationMs": 13.461999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1302.799,
      "heapDeltaBytes": 2316680,
      "heapUsedBytes": 62023928,
      "domNodes": -277,
      "jsHeapTotalBytes": 4984832,
      "scriptDurationMs": 428.535,
      "eventListeners": -144,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3198.4600000000114,
      "styleRecalcs": 65,
      "styleRecalcDurationMs": 14.493999999999996,
      "layouts": 60,
      "layoutDurationMs": 7.063,
      "taskDurationMs": 1468.934,
      "heapDeltaBytes": -773904,
      "heapUsedBytes": 60203888,
      "domNodes": -280,
      "jsHeapTotalBytes": 7663616,
      "scriptDurationMs": 513.547,
      "eventListeners": -148,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3178.058000000078,
      "styleRecalcs": 64,
      "styleRecalcDurationMs": 13.664999999999997,
      "layouts": 60,
      "layoutDurationMs": 7.28,
      "taskDurationMs": 1516.395,
      "heapDeltaBytes": -1632616,
      "heapUsedBytes": 59936556,
      "domNodes": -283,
      "jsHeapTotalBytes": 7401472,
      "scriptDurationMs": 532.054,
      "eventListeners": -148,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "minimap-idle",
      "durationMs": 2040.0119999999902,
      "styleRecalcs": 7,
      "styleRecalcDurationMs": 5.54,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 650.3079999999999,
      "heapDeltaBytes": 7398968,
      "heapUsedBytes": 69648904,
      "domNodes": -274,
      "jsHeapTotalBytes": 4517888,
      "scriptDurationMs": 103.359,
      "eventListeners": -144,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "minimap-idle",
      "durationMs": 2036.004000000048,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 7.481000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 682.1210000000001,
      "heapDeltaBytes": 6752164,
      "heapUsedBytes": 67191216,
      "domNodes": -276,
      "jsHeapTotalBytes": 3993600,
      "scriptDurationMs": 109.09699999999998,
      "eventListeners": -144,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 550.0109999999836,
      "styleRecalcs": 47,
      "styleRecalcDurationMs": 9.729,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 381.106,
      "heapDeltaBytes": -11839064,
      "heapUsedBytes": 56139760,
      "domNodes": 20,
      "jsHeapTotalBytes": 22147072,
      "scriptDurationMs": 112.14699999999999,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 613.2840000000215,
      "styleRecalcs": 49,
      "styleRecalcDurationMs": 11.790000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 407.604,
      "heapDeltaBytes": -11769808,
      "heapUsedBytes": 56180956,
      "domNodes": 24,
      "jsHeapTotalBytes": 22147072,
      "scriptDurationMs": 118.632,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2004.92399999996,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 7.169999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 433.57700000000006,
      "heapDeltaBytes": 3507828,
      "heapUsedBytes": 71494328,
      "domNodes": 18,
      "jsHeapTotalBytes": 21098496,
      "scriptDurationMs": 12.033999999999999,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-idle",
      "durationMs": 1998.97500000003,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 8.666,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 482.52200000000005,
      "heapDeltaBytes": 3592528,
      "heapUsedBytes": 71736988,
      "domNodes": 20,
      "jsHeapTotalBytes": 20574208,
      "scriptDurationMs": 15.632,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1688.2209999999986,
      "styleRecalcs": 77,
      "styleRecalcDurationMs": 35.664,
      "layouts": 16,
      "layoutDurationMs": 3.9180000000000006,
      "taskDurationMs": 730.7790000000001,
      "heapDeltaBytes": -5707512,
      "heapUsedBytes": 62431012,
      "domNodes": 66,
      "jsHeapTotalBytes": 20836352,
      "scriptDurationMs": 87.03800000000001,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1713.9139999999315,
      "styleRecalcs": 76,
      "styleRecalcDurationMs": 34.991,
      "layouts": 16,
      "layoutDurationMs": 3.723,
      "taskDurationMs": 792.6569999999999,
      "heapDeltaBytes": -19588912,
      "heapUsedBytes": 48472368,
      "domNodes": -273,
      "jsHeapTotalBytes": 20176896,
      "scriptDurationMs": 90.235,
      "eventListeners": -148,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-transition-enter",
      "durationMs": 1402.778000000012,
      "styleRecalcs": 19,
      "styleRecalcDurationMs": 30.789000000000012,
      "layouts": 15,
      "layoutDurationMs": 12.54,
      "taskDurationMs": 994.5779999999997,
      "heapDeltaBytes": 9014888,
      "heapUsedBytes": 101072920,
      "domNodes": 13673,
      "jsHeapTotalBytes": 11010048,
      "scriptDurationMs": 37.11699999999998,
      "eventListeners": 2371,
      "totalBlockingTimeMs": 130,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8289.405999999984,
      "styleRecalcs": 251,
      "styleRecalcDurationMs": 37.759,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 4459.450000000001,
      "heapDeltaBytes": 27500964,
      "heapUsedBytes": 85944176,
      "domNodes": -274,
      "jsHeapTotalBytes": 5771264,
      "scriptDurationMs": 1396.595,
      "eventListeners": -128,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8348.428000000013,
      "styleRecalcs": 250,
      "styleRecalcDurationMs": 37.87799999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 4532.459999999999,
      "heapDeltaBytes": 1140496,
      "heapUsedBytes": 59999976,
      "domNodes": -275,
      "jsHeapTotalBytes": 6090752,
      "scriptDurationMs": 1380.646,
      "eventListeners": -158,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 16738.545000000046,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 16696.127,
      "heapDeltaBytes": -41072752,
      "heapUsedBytes": 167046316,
      "domNodes": -8312,
      "jsHeapTotalBytes": -14356480,
      "scriptDurationMs": 566.375,
      "eventListeners": -16387,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.776666666666642,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 16992.929000000004,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 16969.359,
      "heapDeltaBytes": -53853812,
      "heapUsedBytes": 167255664,
      "domNodes": -8312,
      "jsHeapTotalBytes": -13307904,
      "scriptDurationMs": 568.723,
      "eventListeners": -16385,
      "totalBlockingTimeMs": 5,
      "frameDurationMs": 17.779999999999927,
      "p95FrameDurationMs": 16.80000000000291
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 20288.93199999999,
      "styleRecalcs": 135,
      "styleRecalcDurationMs": 15.757999999999994,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 20231.894999999997,
      "heapDeltaBytes": -62098276,
      "heapUsedBytes": 155947028,
      "domNodes": -8312,
      "jsHeapTotalBytes": -13832192,
      "scriptDurationMs": 878.0570000000001,
      "eventListeners": -16379,
      "totalBlockingTimeMs": 136,
      "frameDurationMs": 17.776666666666763,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 20178.45299999999,
      "styleRecalcs": 137,
      "styleRecalcDurationMs": 15.981999999999996,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 20124.743,
      "heapDeltaBytes": -27650612,
      "heapUsedBytes": 180203644,
      "domNodes": -8312,
      "jsHeapTotalBytes": -12607488,
      "scriptDurationMs": 849.33,
      "eventListeners": -16385,
      "totalBlockingTimeMs": 96,
      "frameDurationMs": 17.776666666666642,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "workflow-execution",
      "durationMs": 453.2029999999736,
      "styleRecalcs": 14,
      "styleRecalcDurationMs": 18.833999999999996,
      "layouts": 2,
      "layoutDurationMs": 0.38199999999999995,
      "taskDurationMs": 111.23199999999999,
      "heapDeltaBytes": -15849452,
      "heapUsedBytes": 51122788,
      "domNodes": 130,
      "jsHeapTotalBytes": 7991296,
      "scriptDurationMs": 9.908000000000001,
      "eventListeners": 67,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "workflow-execution",
      "durationMs": 461.8849999999384,
      "styleRecalcs": 13,
      "styleRecalcDurationMs": 18.58,
      "layouts": 2,
      "layoutDurationMs": 0.30100000000000005,
      "taskDurationMs": 110.99699999999999,
      "heapDeltaBytes": -15981416,
      "heapUsedBytes": 51145768,
      "domNodes": 119,
      "jsHeapTotalBytes": 7729152,
      "scriptDurationMs": 9.611999999999998,
      "eventListeners": 65,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    }
  ]
}

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

@@            Coverage Diff             @@
##             main   #14217      +/-   ##
==========================================
+ Coverage   79.44%   79.67%   +0.22%     
==========================================
  Files        1754     1755       +1     
  Lines      111080    98054   -13026     
  Branches    37281    31270    -6011     
==========================================
- Hits        88250    78123   -10127     
+ Misses      22282    19552    -2730     
+ Partials      548      379     -169     
Flag Coverage Δ
unit 69.41% <100.00%> (+0.25%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/platform/assets/services/assetService.ts 82.01% <100.00%> (+26.66%) ⬆️

... and 207 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@synap5e synap5e added the cursor-review Trigger multi-model Cursor agent review on this PR label Jul 28, 2026
@synap5e synap5e changed the title fix(assets): fall back to bare-tag grouping for legacy tags in model_type mode (stacked on #13574) fix(assets): fall back to bare-tag grouping for legacy tags in model_type mode Jul 28, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Cursor Review — Consolidated panel

Triggered by @synap5e.

Found 2 finding(s).

Severity Count
🟠 High 1
🟢 Low 1

Panel: 8/8 reviewers contributed findings.

return tag.startsWith(MODEL_TYPE_TAG_PREFIX)
? tag.slice(MODEL_TYPE_TAG_PREFIX.length)
: undefined
if (modelTypeMode && tag.startsWith(MODEL_TYPE_TAG_PREFIX)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High — The bare-tag fallback now fires per-tag without checking whether the asset already carries authoritative model_type: tags. During the partial re-tagging this change targets, an asset carrying both model_type:checkpoints and a bare checkpoints twin resolves to checkpoints twice — and since buildModelBuckets does not de-duplicate the folder list, the asset is pushed into the same bucket twice (duplicate sidebar rows / duplicate Vue keys and duplicate getAssetModels entries); separately, an unrelated bare tag that matches another folder cross-lists a covered asset into the wrong loader (risking loading a different same-named model). Only fall back to bare-tag grouping when the asset has no model_type: tag, and de-duplicate the resolved folders as defense-in-depth. Raised by 6 of 8 reviewers (gpt-5.6-sol-max edge-case, gemini-3.1-pro edge-case, gpt-5.6-sol-max adversarial, claude-opus-4-8-thinking-max edge-case, claude-opus-4-8-thinking-max adversarial, kimi-k2.7-code edge-case).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review. Both findings addressed in 80b587e (pushed to this branch):

  • High: replaced the per-tag modelFolderFromTag walk with the existing, already-tested asset-level resolver getAssetCategories(asset, modelTypeMode), de-duped via Set. An asset with both a model_type: tag and a bare twin no longer double-buckets or cross-lists.
  • Low: left as a documented known limitation, narrowed to only affect assets with no model_type: tag at all and only junk bare tags. There's no static known-folder-categories list in the codebase to restrict against without a larger restructure, so fixing this fully is out of scope here.

Generated by Claude Code

return tag.slice(MODEL_TYPE_TAG_PREFIX.length)
}
if (tag === MODELS_TAG || tag.length === 0) return undefined
return tag.split('/')[0]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Low — Previously a non-namespaced tag returned undefined in model-type mode, so an asset with only junk/descriptive bare tags (no real category) was dropped and surfaced the 'has no model category; skipping' diagnostic. Now every bare tag mints a phantom folder bucket, so genuinely mis-tagged assets are silently filed under stray keys and the warning is lost. Consider restricting the fallback to known folder categories or preserving the diagnostic path. Raised by 2 of 8 reviewers (claude-opus-4-8-thinking-max adversarial, claude-opus-4-8-thinking-max edge-case).

… alone

modelFolderFromTag resolved a bare-tag fallback per-tag with no visibility
into the rest of an asset's tags, so an asset caught mid-retag (carrying both
model_type:checkpoints and its pre-migration checkpoints twin) resolved to
'checkpoints' twice and buildModelBuckets pushed it into that bucket twice
(duplicate sidebar rows). A leftover unrelated bare tag could also cross-list
an already-covered asset into a folder it does not belong in.

Replace the per-tag walk with getAssetCategories, which already resolves an
asset's categories correctly at the asset level elsewhere in the codebase
(useAssetBrowser, assetFilterUtils): a model_type-covered asset groups by its
model_type: tags alone, bare tags only apply as a fallback for uncovered
assets. Also de-dupe the resolved folder list as defense in depth.
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels Jul 28, 2026
claude added 2 commits July 28, 2026 22:51
Asset mode hides sidebar folders that load with zero models
(modelStore's visibleModelFolders), so an empty 'loras' folder never
renders a row at all. The new mid-retag-twin test relied on clicking
that row, which timed out on every CI run since the fix under test
correctly keeps the mid-retag asset's loras bare tag from populating
it. Add a real model_type:loras asset so the folder renders, then
assert the mid-retag asset's leaf is absent from it.
The whole-tree locator counted the leaf still legitimately rendered
under the still-expanded checkpoints folder, so the assertion that it
is absent from loras failed deterministically (received 1, not 0) even
though the app correctly excludes it. Scope the query to the loras
folder's own subtree instead.
Base automatically changed from synap5e/test/assets-sidebar-e2e to main July 28, 2026 23:13
@claude
claude Bot requested a review from a team July 28, 2026 23:13
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Jul 28, 2026
…odel-type-fallback

# Conflicts:
#	browser_tests/fixtures/data/assetFixtures.ts
#	browser_tests/tests/sidebar/modelLibraryAssetMode.spec.ts
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Jul 28, 2026
The three new getAssetModels tests (bare-tag fallback, mid-retag
de-dupe, cross-list guard) re-assert the exact scenarios already
proven end-to-end by modelLibraryAssetMode.spec.ts, and the
underlying category-resolution logic they exercise is already
pinned directly against getAssetCategories in
assetMetadataUtils.test.ts. buildModelBuckets/getAssetModels now
just delegate to getAssetCategories, so these tests added no
coverage beyond confirming that delegation, which the pre-existing
tests in this same describe block (walks the models tag once,
buckets by bare tags when unsupported) already establish.
@synap5e

synap5e commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Recreated as #14848 under my own account for tracking.

@synap5e synap5e closed this Aug 6, 2026
pull Bot pushed a commit to Penguinjanator/ComfyUI_frontend that referenced this pull request Aug 12, 2026
…type mode (Comfy-Org#14848)

## Summary

Fixes a bug where a legacy bare-tagged model asset silently disappears
from the model library sidebar once the backend advertises `model_type:`
support, instead of falling back to legacy bare-tag grouping.

_Recreated from Comfy-Org#14217 — same change, opened directly under my own
account for tracking. The High finding from Cursor's panel on that PR is
already folded into this diff._

## Changes

- **What**: `modelFolderFromTag` returned `undefined` for any tag that
didn't carry the `model_type:` prefix as soon as `modelTypeMode` was
`true`. `buildModelBuckets` treats an asset whose tags resolve to no
folder as "uncategorized" and drops it with a `console.warn`, so a model
still carrying a legacy bare tag (e.g. `checkpoints` instead of
`model_type:checkpoints`) vanished from the sidebar entirely on a
`model_type:`-capable backend. Changed in
`src/platform/assets/services/assetService.ts`.
- **Breaking**: none

## How

The fix deletes the local `modelFolderFromTag` helper and buckets via
`getAssetCategories` from `assetMetadataUtils`, which already implements
exactly the intended semantics and is already used by the other asset
surfaces: `model_type:*` values are authoritative when present, and an
asset with no `model_type:` tag still routes by its bare tags (with
namespace residue filtered out). This makes the sidebar consistent with
the rest of the asset code rather than carrying a second, subtly
different grouping rule.

A side effect worth calling out: because `getAssetCategories` returns
`model_type:` values *alone* when an asset has any, an asset covered by
`model_type:` tags can no longer be cross-listed into a second folder by
a leftover bare-tag twin from a partial re-tagging. The e2e suite covers
that case (the "mid-retag twin" scenario).

Added an e2e scenario, `Model library sidebar - asset mode with a legacy
bare tag`, in
`browser_tests/tests/sidebar/modelLibraryAssetMode.spec.ts`, plus a
matching fixture (`MODEL_TYPE_CHECKPOINT_LEGACY_TAG` in
`browser_tests/fixtures/data/assetFixtures.ts`): a bare-tagged asset
that still carries a `loader_path`, walked with
`supports_model_type_tags: true`, asserting it still renders in the
`checkpoints` folder rather than being dropped.

## Review Focus

- This targets `main` directly. The stack it was originally written on
top of (Comfy-Org#13574) has since merged, so the diff here is just the three
files.
- Coverage for the regression lives in the e2e spec rather than a unit
test — the unit-level version was dropped as duplicating it. Flagging
that explicitly since it is a judgement call about test placement.
- Verified against `main` that the bug is still live:
`modelFolderFromTag` on `main` still returns `undefined` for bare tags
whenever `modelTypeMode` is true.
- Checked that the existing `assetService.test.ts` cases on `main`
remain valid under the new path: `getBareTagCategories` filters out the
reserved `models` tag, so the "drops uncategorized model assets with a
warning" case still drops its `tags: ['models']` asset; the bare-tag
grouping cases all run with `supports_model_type_tags = false`, an
unchanged path.

## Test plan

- [ ] `pnpm typecheck` — **not run**: no Node/pnpm toolchain provisioned
on the host I authored this on. Relying on CI.
- [ ] `pnpm exec vitest run
src/platform/assets/services/assetService.test.ts` — **not run**, same
reason. Compatibility with the existing cases was verified by reading
them (see Review Focus).
- [x] Static check that the refactor is complete:
`MODEL_TYPE_TAG_PREFIX` import removed with no remaining uses in the
file, `modelFolderFromTag` has zero references repo-wide,
`getAssetCategories` is exported from `assetMetadataUtils` on `main`.
- [x] The identical three-file diff passed a full CI run on Comfy-Org#14217
(Playwright 1759 passed / 0 failed / 1 flaky; Codecov reported all
modified lines covered).

---

**Review coverage note:** no Cursor panel has run on this PR — verified
by querying for the panel review itself rather than inferring from an
empty findings list. That is a *did-not-run*, not a clean result; the
checks API reports success either way. CodeRabbit was rate-limited.
Codex did review it, and its one finding was addressed in `f16560c`.

_(An earlier version of this note blamed an org-wide Cursor outage
running to 2026-08-22. That attribution was wrong and is withdrawn —
panels have since been seen running normally elsewhere. The measured
fact, that none ran here, is unchanged.)_

---------

Co-authored-by: Austin Mroz <austin@comfy.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cursor-review Trigger multi-model Cursor agent review on this PR size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants