Skip to content

fix(i18n): clamp unsupported browser locales to a shipped tag#11712

Open
dante01yoon wants to merge 5 commits intomainfrom
jaewon/fe-480-fix-unsupported-locale
Open

fix(i18n): clamp unsupported browser locales to a shipped tag#11712
dante01yoon wants to merge 5 commits intomainfrom
jaewon/fe-480-fix-unsupported-locale

Conversation

@dante01yoon
Copy link
Copy Markdown
Collaborator

@dante01yoon dante01yoon commented Apr 28, 2026

Summary

Sidebar buttons rendered literal i18n keys (e.g. sideToolbar.labels.assets) on a fresh install when the user's navigator.language base tag wasn't one of the 12 shipped locales — German/Italian/Polish/Dutch/Brazilian-Portuguese users among others.

Changes

  • What: Add resolveSupportedLocale() that tries the full BCP-47 tag first (preserves zh-TW, pt-BR), then the base tag, then 'en'. Wire through both entry points (createI18n's initial locale, Comfy.Locale's defaultValue) and clamp inside loadLocale, propagating the resolved tag to GraphView so a stale stored Comfy.Locale='de' from older builds also recovers.
  • Side benefit: Brazilian Portuguese users were previously falling through pt-BRpt (unshipped) → broken. The full-tag-first lookup now correctly lands them on the pt-BR bundle.
  • Breaking: None.
  • Dependencies: None.

Root Cause

Three-link chain:

  1. Comfy.Locale's default was () => navigator.language.split('-')[0] || 'en'. German → 'de' (unshipped).
  2. loadLocale('de') silently console.warn'd and returned without throwing.
  3. GraphView then ran i18n.global.locale.value = 'de' anyway.
  4. st(key, fallback) = te(key) ? t(key) : fallback. vue-i18n's te() checks only the current locale and ignores fallbackLocale — every key missed → st() returned the literal key string.

Two pathways reached the broken state (defaultValue path, and unset-setting path through createI18n's own navigator.language snapshot); the new helper closes both.

Review Focus

  • loadLocale now returns SupportedLocale (was void). Old void callers continue to compile; the only change is GraphView consuming the return value.
  • Unit-tested in src/i18n.test.ts (added resolveSupportedLocale block + updated the loadLocale unsupported-locale case from "warn" to "clamp to en").
  • Self-reproduced via Playwright with navigator.language='de-DE' + fresh-install state on both main (shows the bug) and this branch (shows the fix). Spec saved at temp/scripts/issue-10563-locale-bug.spec.ts.

Fixes #10563
FE-480 — https://linear.app/comfyorg/issue/FE-480

Screenshots

Before (from #10563, on main):

Sidebar with literal i18n keys

After (this branch, same navigator.language='de-DE'):

Screenshot 2026-04-28 at 2 07 38 PM

┆Issue is synchronized with this Notion page by Unito

navigator.language base tags outside the 12 shipped locales (de, it, nl,
pl, pt, vi, hi, etc.) caused Comfy.Locale's defaultValue and createI18n's
initial locale to set i18n.global.locale.value to a tag with no messages.
loadLocale silently no-op'd, te() returned false for the missing locale
(it does not consult fallbackLocale), and st() rendered the literal i18n
key — so on a fresh install the sidebar buttons displayed
'sideToolbar.labels.assets' etc. instead of 'Assets'.

Add resolveSupportedLocale() that tries the full BCP-47 tag first
(preserving zh-TW/pt-BR), then the base tag, then 'en'. Wire it through
both entry points (createI18n initial locale, Comfy.Locale defaultValue)
and clamp inside loadLocale + propagate the resolved value to GraphView
so a stale stored Comfy.Locale='de' from older builds also recovers.

Side benefit: pt-BR users were previously falling through pt → unshipped
→ broken; the full-tag-first lookup now lands them on the pt-BR bundle.

Fixes #10563
FE-480
@dante01yoon dante01yoon requested a review from a team April 28, 2026 04:52
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Apr 28, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6a2d58fb-6a78-4bdc-ba10-50818b492078

📥 Commits

Reviewing files that changed from the base of the PR and between d6f1b9c and e703826.

📒 Files selected for processing (1)
  • src/locales/CONTRIBUTING.md

📝 Walkthrough

Walkthrough

Adds a centralized locale configuration and resolver, refactors locale loading to always resolve requested locales to supported canonical values, updates initialization and settings to use the resolver, and adapts tests and a browser test to assert clamping, canonicalization, and preserved shipped tags.

Changes

Cohort / File(s) Summary
Locale Config & Types
src/locales/localeConfig.ts
New localeDefinitions, SupportedLocale type, SUPPORTED_LOCALE_OPTIONS, and resolveSupportedLocale(input) implementing exact, case-insensitive, base-tag fallback, and 'en' default.
I18n Core
src/i18n.ts
Replaced per-locale loader map with localeDefinitions-driven loaders; loadLocale(locale) now resolves to a canonical SupportedLocale, dedupes loading, registers/merges messages by resolved locale, and returns the resolved locale. Re-exports resolveSupportedLocale.
Settings & UI Integration
src/platform/settings/constants/coreSettings.ts, src/views/GraphView.vue
Comfy.Locale options sourced from SUPPORTED_LOCALE_OPTIONS; default locale computed via resolveSupportedLocale(navigator.language); GraphView assigns i18n locale from loadLocale(...) return (resolved value).
Tests (unit)
src/i18n.test.ts
Tests now import i18n via a typed dynamic helper, assert clamping/normalization behavior instead of console warnings, and add a resolveSupportedLocale test suite covering passthrough, case normalization, base-tag fallback, and 'en' fallback.
Browser Tests
browser_tests/tests/templates.spec.ts
Fallback-to-English test switched to a shipped locale (fa), intercepts templates/index.${locale}.json (404) while allowing templates/index.json, and verifies request URL plus locale-stable content id.
Documentation
src/locales/CONTRIBUTING.md
Docs updated to instruct adding locale entries to localeConfig.ts (display text + lazy JSON import loaders) instead of editing coreSettings.ts/i18n.ts.

Sequence Diagram(s)

sequenceDiagram
    participant Browser as Browser\nNavigator
    participant Settings as App\nSettings
    participant Resolver as resolveSupportedLocale
    participant Loader as loadLocale
    participant I18n as Vue I18n

    Browser->>Settings: navigator.language (e.g., "de-DE")
    Settings->>Resolver: resolveSupportedLocale("de-DE")
    activate Resolver
    Resolver->>Resolver: case-insensitive exact match?
    alt exact shipped
        Resolver-->>Settings: return canonical (e.g., "zh-TW")
    else not shipped
        Resolver->>Resolver: check base subtag (e.g., "de")
        alt base shipped
            Resolver-->>Settings: return base canonical (e.g., "pt")
        else
            Resolver-->>Settings: return "en"
        end
    end
    deactivate Resolver

    Settings->>Loader: loadLocale(resolved)
    activate Loader
    Loader->>Loader: dedupe in-flight, dynamic import messages
    Loader->>I18n: set/mergeLocaleMessage(resolved, messages)
    Loader->>I18n: set i18n.locale = resolved
    Loader-->>Settings: return resolved
    deactivate Loader
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I sniff a tag, messy, mixed, and wild,
I hop and match it till it's nicely styled.
Exact or base — I find where it belongs,
Or nudge it home to English with a song.
Hooray — locales tidy, the UI hums along! ✨

🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(i18n): clamp unsupported browser locales to a shipped tag' accurately summarizes the main change—adding locale resolution logic to clamp unsupported browser locales to supported shipped tags.
Description check ✅ Passed The description comprehensively covers the summary, root cause analysis, detailed changes with breaking/dependency notes, review focus, and references both issue #10563 and linear issue FE-480, with before/after screenshots demonstrating the fix.
Linked Issues check ✅ Passed The PR addresses all objectives from #10563: adds resolveSupportedLocale() that tries full BCP-47 tags first then falls back to base tag or 'en' [#10563], wires the resolver through createI18n and Comfy.Locale defaultValue [#10563], clamps in loadLocale and propagates to GraphView [#10563], with unit tests added [#10563].
Out of Scope Changes check ✅ Passed All changes are scoped to locale resolution: new localeConfig.ts module, refactored loadLocale/createI18n, updated GraphView and coreSettings, modified i18n.ts tests, and documentation updates—all directly supporting the fix for unsupported locale clamping.
End-To-End Regression Coverage For Fixes ✅ Passed PR includes bug-fix language and contains changes to browser_tests/tests/templates.spec.ts validating the locale fallback behavior.
Adr Compliance For Entity/Litegraph Changes ✅ Passed PR does not modify files under src/lib/litegraph/, src/ecs/, or graph entity files. Changes focus exclusively on i18n and locale handling.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jaewon/fe-480-fix-unsupported-locale

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

🎨 Storybook: ✅ Built — View Storybook

Details

⏰ Completed at: 04/30/2026, 08:42:45 AM UTC

Links

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

🎭 Playwright: ✅ 1435 passed, 0 failed

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

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

📦 Bundle: 5.23 MB gzip 🔴 +377 B

Details

Summary

  • Raw size: 24.1 MB baseline 24.1 MB — 🔴 +936 B
  • Gzip: 5.23 MB baseline 5.23 MB — 🔴 +377 B
  • Brotli: 4.05 MB baseline 4.05 MB — 🔴 +251 B
  • Bundles: 257 current • 257 baseline • 126 added / 126 removed

Category Glance
Other 🔴 +1.45 kB (8.83 MB) · Graph Workspace 🟢 -512 B (1.24 MB) · Vendor & Third-Party ⚪ 0 B (9.88 MB) · Data & Services ⚪ 0 B (3.04 MB) · Panels & Settings ⚪ 0 B (488 kB) · Utilities & Hooks ⚪ 0 B (364 kB) · + 5 more

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

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-B2yxdoPM.js (removed) 22.5 kB 🟢 -22.5 kB 🟢 -7.99 kB 🟢 -6.87 kB
assets/index-DKjcyOfJ.js (new) 22.5 kB 🔴 +22.5 kB 🔴 +7.99 kB 🔴 +6.86 kB

Status: 1 added / 1 removed

Graph Workspace — 1.24 MB (baseline 1.24 MB) • 🟢 -512 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-LP7qrDTj.js (removed) 1.24 MB 🟢 -1.24 MB 🟢 -265 kB 🟢 -199 kB
assets/GraphView-D4X8GHfZ.js (new) 1.24 MB 🔴 +1.24 MB 🔴 +264 kB 🔴 +199 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-Ba6gs3P7.js (new) 15.7 kB 🔴 +15.7 kB 🔴 +3.41 kB 🔴 +2.92 kB
assets/CloudSurveyView-KGtIcz4c.js (removed) 15.7 kB 🟢 -15.7 kB 🟢 -3.41 kB 🟢 -2.92 kB
assets/CloudLoginView-BGOXcIAR.js (new) 12.2 kB 🔴 +12.2 kB 🔴 +3.43 kB 🔴 +3.04 kB
assets/CloudLoginView-Wyh192en.js (removed) 12.2 kB 🟢 -12.2 kB 🟢 -3.43 kB 🟢 -3.04 kB
assets/CloudSignupView-D-y-ZswY.js (new) 9.94 kB 🔴 +9.94 kB 🔴 +2.93 kB 🔴 +2.58 kB
assets/CloudSignupView-Dwko-v4H.js (removed) 9.94 kB 🟢 -9.94 kB 🟢 -2.93 kB 🟢 -2.58 kB
assets/UserCheckView-B-Y69Hlr.js (new) 9.07 kB 🔴 +9.07 kB 🔴 +2.34 kB 🔴 +2.05 kB
assets/UserCheckView-D8sBURKn.js (removed) 9.07 kB 🟢 -9.07 kB 🟢 -2.33 kB 🟢 -2.04 kB
assets/CloudLayoutView-BGe0vqDr.js (removed) 7.7 kB 🟢 -7.7 kB 🟢 -2.43 kB 🟢 -2.12 kB
assets/CloudLayoutView-CHKdvNPh.js (new) 7.7 kB 🔴 +7.7 kB 🔴 +2.43 kB 🔴 +2.1 kB
assets/CloudForgotPasswordView-Bp12T1f1.js (new) 6.11 kB 🔴 +6.11 kB 🔴 +2.17 kB 🔴 +1.9 kB
assets/CloudForgotPasswordView-WMaiW-TE.js (removed) 6.11 kB 🟢 -6.11 kB 🟢 -2.17 kB 🟢 -1.93 kB
assets/CloudAuthTimeoutView-B1rbiWk_.js (removed) 5.47 kB 🟢 -5.47 kB 🟢 -2 kB 🟢 -1.76 kB
assets/CloudAuthTimeoutView-DTA9O9xO.js (new) 5.47 kB 🔴 +5.47 kB 🔴 +2.01 kB 🔴 +1.75 kB
assets/CloudSubscriptionRedirectView-Bcbsky-y.js (removed) 5.25 kB 🟢 -5.25 kB 🟢 -1.98 kB 🟢 -1.76 kB
assets/CloudSubscriptionRedirectView-BVZ079Uw.js (new) 5.25 kB 🔴 +5.25 kB 🔴 +1.98 kB 🔴 +1.76 kB
assets/UserSelectView-B36m0Zyn.js (removed) 4.73 kB 🟢 -4.73 kB 🟢 -1.75 kB 🟢 -1.55 kB
assets/UserSelectView-I_G05hW-.js (new) 4.73 kB 🔴 +4.73 kB 🔴 +1.75 kB 🔴 +1.55 kB

Status: 9 added / 9 removed / 2 unchanged

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/KeybindingPanel-DCcyFr1H.js (removed) 46.7 kB 🟢 -46.7 kB 🟢 -9.61 kB 🟢 -8.53 kB
assets/KeybindingPanel-uDo22jpI.js (new) 46.7 kB 🔴 +46.7 kB 🔴 +9.61 kB 🔴 +8.53 kB
assets/SecretsPanel-CpSmCOct.js (new) 22.9 kB 🔴 +22.9 kB 🔴 +5.54 kB 🔴 +4.88 kB
assets/SecretsPanel-DjcU1h23.js (removed) 22.9 kB 🟢 -22.9 kB 🟢 -5.54 kB 🟢 -4.88 kB
assets/LegacyCreditsPanel-0yudnZ4r.js (removed) 21.7 kB 🟢 -21.7 kB 🟢 -5.89 kB 🟢 -5.19 kB
assets/LegacyCreditsPanel-DSIFZGng.js (new) 21.7 kB 🔴 +21.7 kB 🔴 +5.89 kB 🔴 +5.2 kB
assets/SubscriptionPanel-BW8xIfYL.js (removed) 19.9 kB 🟢 -19.9 kB 🟢 -5.07 kB 🟢 -4.45 kB
assets/SubscriptionPanel-D2pYaTBs.js (new) 19.9 kB 🔴 +19.9 kB 🔴 +5.06 kB 🔴 +4.45 kB
assets/AboutPanel-DkrkI2hz.js (new) 12 kB 🔴 +12 kB 🔴 +3.33 kB 🔴 +2.98 kB
assets/AboutPanel-Dz28USoe.js (removed) 12 kB 🟢 -12 kB 🟢 -3.33 kB 🟢 -3 kB
assets/ExtensionPanel-0nvuTybZ.js (new) 9.94 kB 🔴 +9.94 kB 🔴 +2.9 kB 🔴 +2.58 kB
assets/ExtensionPanel-C19L8CpN.js (removed) 9.94 kB 🟢 -9.94 kB 🟢 -2.9 kB 🟢 -2.57 kB
assets/ServerConfigPanel-7dAfZCWz.js (removed) 7.02 kB 🟢 -7.02 kB 🟢 -2.35 kB 🟢 -2.1 kB
assets/ServerConfigPanel-B-HJjLnF.js (new) 7.02 kB 🔴 +7.02 kB 🔴 +2.35 kB 🔴 +2.1 kB
assets/UserPanel-BcxgTt-7.js (removed) 6.73 kB 🟢 -6.73 kB 🟢 -2.23 kB 🟢 -1.95 kB
assets/UserPanel-DA4foZkK.js (new) 6.73 kB 🔴 +6.73 kB 🔴 +2.23 kB 🔴 +1.95 kB
assets/cloudRemoteConfig-CIN5MM2E.js (new) 2.02 kB 🔴 +2.02 kB 🔴 +976 B 🔴 +838 B
assets/cloudRemoteConfig-OVeKsUzY.js (removed) 2.02 kB 🟢 -2.02 kB 🟢 -973 B 🟢 -833 B
assets/refreshRemoteConfig-CeMwRE1Y.js (removed) 1.45 kB 🟢 -1.45 kB 🟢 -648 B 🟢 -554 B
assets/refreshRemoteConfig-iaH_tuf6.js (new) 1.45 kB 🔴 +1.45 kB 🔴 +648 B 🔴 +552 B

Status: 10 added / 10 removed / 11 unchanged

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

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/auth-BtKbH846.js (new) 3.57 kB 🔴 +3.57 kB 🔴 +1.26 kB 🔴 +1.07 kB
assets/auth-CmIcgzrH.js (removed) 3.57 kB 🟢 -3.57 kB 🟢 -1.26 kB 🟢 -1.07 kB
assets/SignUpForm-BLumvrdV.js (new) 3.2 kB 🔴 +3.2 kB 🔴 +1.29 kB 🔴 +1.17 kB
assets/SignUpForm-DcgCkOcg.js (removed) 3.2 kB 🟢 -3.2 kB 🟢 -1.29 kB 🟢 -1.17 kB
assets/UpdatePasswordContent-ChgeFJBZ.js (removed) 2.87 kB 🟢 -2.87 kB 🟢 -1.29 kB 🟢 -1.14 kB
assets/UpdatePasswordContent-CI_MyIzi.js (new) 2.87 kB 🔴 +2.87 kB 🔴 +1.29 kB 🔴 +1.15 kB
assets/authStore-DKhKoMLQ.js (new) 1.16 kB 🔴 +1.16 kB 🔴 +555 B 🔴 +493 B
assets/authStore-DuAc2Vlc.js (removed) 1.16 kB 🟢 -1.16 kB 🟢 -552 B 🟢 -495 B
assets/auth-Ch4EJbC1.js (new) 348 B 🔴 +348 B 🔴 +218 B 🔴 +189 B
assets/auth-DUuxlOEd.js (removed) 348 B 🟢 -348 B 🟢 -216 B 🟢 -212 B

Status: 5 added / 5 removed / 2 unchanged

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

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyHubPublishDialog-Bo3bSVhR.js (new) 86.9 kB 🔴 +86.9 kB 🔴 +18.8 kB 🔴 +16 kB
assets/ComfyHubPublishDialog-CWF5r_6C.js (removed) 86.9 kB 🟢 -86.9 kB 🟢 -18.8 kB 🟢 -16.1 kB
assets/useShareDialog-DMi8DgpK.js (new) 23.7 kB 🔴 +23.7 kB 🔴 +5.77 kB 🔴 +5.11 kB
assets/useShareDialog-DulvMpv8.js (removed) 23.7 kB 🟢 -23.7 kB 🟢 -5.77 kB 🟢 -5.11 kB
assets/ComfyHubPublishDialog-7U82m0nF.js (removed) 1.32 kB 🟢 -1.32 kB 🟢 -614 B 🟢 -558 B
assets/ComfyHubPublishDialog-B2NVidzW.js (new) 1.32 kB 🔴 +1.32 kB 🔴 +614 B 🔴 +542 B
assets/useSubscriptionDialog-oaai1Jjy.js (new) 1.14 kB 🔴 +1.14 kB 🔴 +545 B 🔴 +479 B
assets/useSubscriptionDialog-ZtrYg4Ss.js (removed) 1.14 kB 🟢 -1.14 kB 🟢 -544 B 🟢 -479 B

Status: 4 added / 4 removed

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

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-BoJZH18Z.js (new) 13.5 kB 🔴 +13.5 kB 🔴 +3.79 kB 🔴 +3.38 kB
assets/ComfyQueueButton-qkevSVdR.js (removed) 13.5 kB 🟢 -13.5 kB 🟢 -3.79 kB 🟢 -3.38 kB
assets/useTerminalTabs-DlXYAQTL.js (new) 11 kB 🔴 +11 kB 🔴 +3.71 kB 🔴 +3.27 kB
assets/useTerminalTabs-DwQ4lJzb.js (removed) 11 kB 🟢 -11 kB 🟢 -3.71 kB 🟢 -3.27 kB
assets/SubscribeButton-D9KFAS7T.js (removed) 2.42 kB 🟢 -2.42 kB 🟢 -1.05 kB 🟢 -935 B
assets/SubscribeButton-DgZmDqaC.js (new) 2.42 kB 🔴 +2.42 kB 🔴 +1.05 kB 🔴 +942 B
assets/cloudFeedbackTopbarButton-DbgSNbxV.js (removed) 1.8 kB 🟢 -1.8 kB 🟢 -930 B 🟢 -829 B
assets/cloudFeedbackTopbarButton-DqlFgi1c.js (new) 1.8 kB 🔴 +1.8 kB 🔴 +930 B 🔴 +825 B
assets/ComfyQueueButton-DfgrT4kB.js (removed) 1.24 kB 🟢 -1.24 kB 🟢 -579 B 🟢 -518 B
assets/ComfyQueueButton-DklJ0thm.js (new) 1.24 kB 🔴 +1.24 kB 🔴 +582 B 🔴 +516 B

Status: 5 added / 5 removed / 8 unchanged

Data & Services — 3.04 MB (baseline 3.04 MB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/dialogService-BJ_WGf_2.js (new) 1.97 MB 🔴 +1.97 MB 🔴 +454 kB 🔴 +344 kB
assets/dialogService-CTZ3hIJu.js (removed) 1.97 MB 🟢 -1.97 MB 🟢 -454 kB 🟢 -344 kB
assets/api-BC-lJc6q.js (new) 894 kB 🔴 +894 kB 🔴 +214 kB 🔴 +168 kB
assets/api-BulVpDMl.js (removed) 894 kB 🟢 -894 kB 🟢 -214 kB 🟢 -168 kB
assets/load3dService-8uc456Hc.js (removed) 114 kB 🟢 -114 kB 🟢 -24.8 kB 🟢 -21 kB
assets/load3dService-lgjUtrt6.js (new) 114 kB 🔴 +114 kB 🔴 +24.8 kB 🔴 +21.1 kB
assets/workflowShareService-CJhl7rhQ.js (new) 16.6 kB 🔴 +16.6 kB 🔴 +4.89 kB 🔴 +4.33 kB
assets/workflowShareService-h116tBtV.js (removed) 16.6 kB 🟢 -16.6 kB 🟢 -4.89 kB 🟢 -4.33 kB
assets/keybindingService-DI8N-xqp.js (removed) 13.8 kB 🟢 -13.8 kB 🟢 -3.67 kB 🟢 -3.22 kB
assets/keybindingService-gulIzw4A.js (new) 13.8 kB 🔴 +13.8 kB 🔴 +3.67 kB 🔴 +3.22 kB
assets/releaseStore-DmzEgZGZ.js (new) 8.12 kB 🔴 +8.12 kB 🔴 +2.28 kB 🔴 +2 kB
assets/releaseStore-Uzr6Ete3.js (removed) 8.12 kB 🟢 -8.12 kB 🟢 -2.28 kB 🟢 -2 kB
assets/userStore-Bh-CSpBW.js (removed) 2.24 kB 🟢 -2.24 kB 🟢 -869 B 🟢 -761 B
assets/userStore-DGSZwuDr.js (new) 2.24 kB 🔴 +2.24 kB 🔴 +870 B 🔴 +760 B
assets/audioService-Bmbzo7Nz.js (removed) 1.8 kB 🟢 -1.8 kB 🟢 -876 B 🟢 -761 B
assets/audioService-DrEtCIiz.js (new) 1.8 kB 🔴 +1.8 kB 🔴 +877 B 🔴 +761 B
assets/releaseStore-DBKCi0px.js (new) 1.16 kB 🔴 +1.16 kB 🔴 +549 B 🔴 +485 B
assets/releaseStore-vyYfir3q.js (removed) 1.16 kB 🟢 -1.16 kB 🟢 -546 B 🟢 -493 B
assets/workflowDraftStore-CKWpLHj6.js (new) 1.14 kB 🔴 +1.14 kB 🔴 +544 B 🔴 +484 B
assets/workflowDraftStore-CYTwNovY.js (removed) 1.14 kB 🟢 -1.14 kB 🟢 -543 B 🟢 -482 B
assets/dialogService-4DiTgjdz.js (removed) 1.13 kB 🟢 -1.13 kB 🟢 -536 B 🟢 -475 B
assets/dialogService-CLIDtPWi.js (new) 1.13 kB 🔴 +1.13 kB 🔴 +537 B 🔴 +477 B
assets/settingStore-Ctlnt7Tp.js (new) 1.12 kB 🔴 +1.12 kB 🔴 +539 B 🔴 +476 B
assets/settingStore-YlblIQcM.js (removed) 1.12 kB 🟢 -1.12 kB 🟢 -539 B 🟢 -475 B
assets/assetsStore-BwkjW15t.js (removed) 1.12 kB 🟢 -1.12 kB 🟢 -538 B 🟢 -478 B
assets/assetsStore-cDfdRN5q.js (new) 1.12 kB 🔴 +1.12 kB 🔴 +539 B 🔴 +478 B

Status: 13 added / 13 removed / 4 unchanged

Utilities & Hooks — 364 kB (baseline 364 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useConflictDetection-Bi4wouZ5.js (new) 233 kB 🔴 +233 kB 🔴 +51.8 kB 🔴 +42.2 kB
assets/useConflictDetection-Dd0uNGFy.js (removed) 233 kB 🟢 -233 kB 🟢 -51.8 kB 🟢 -42.3 kB
assets/useLoad3d-BrJZMQnA.js (new) 22.3 kB 🔴 +22.3 kB 🔴 +5.09 kB 🔴 +4.49 kB
assets/useLoad3d-cDvknNkj.js (removed) 22.3 kB 🟢 -22.3 kB 🟢 -5.09 kB 🟢 -4.51 kB
assets/useLoad3dViewer-3j9DetL3.js (new) 20.8 kB 🔴 +20.8 kB 🔴 +4.91 kB 🔴 +4.3 kB
assets/useLoad3dViewer-D6ZYM18g.js (removed) 20.8 kB 🟢 -20.8 kB 🟢 -4.91 kB 🟢 -4.3 kB
assets/useFeatureFlags-DFBsSJDT.js (removed) 5.95 kB 🟢 -5.95 kB 🟢 -1.79 kB 🟢 -1.53 kB
assets/useFeatureFlags-DJSZS7Yf.js (new) 5.95 kB 🔴 +5.95 kB 🔴 +1.8 kB 🔴 +1.53 kB
assets/useCopyToClipboard-C8OcWzHx.js (removed) 5.29 kB 🟢 -5.29 kB 🟢 -1.86 kB 🟢 -1.57 kB
assets/useCopyToClipboard-DRCXjGDk.js (new) 5.29 kB 🔴 +5.29 kB 🔴 +1.86 kB 🔴 +1.57 kB
assets/downloadUtil-BFqX5xDF.js (new) 4.68 kB 🔴 +4.68 kB 🔴 +1.85 kB 🔴 +1.54 kB
assets/downloadUtil-BPib-9zU.js (removed) 4.68 kB 🟢 -4.68 kB 🟢 -1.85 kB 🟢 -1.53 kB
assets/useWorkspaceUI-D9-oQVd6.js (removed) 3.34 kB 🟢 -3.34 kB 🟢 -982 B 🟢 -808 B
assets/useWorkspaceUI-GyiHHhOZ.js (new) 3.34 kB 🔴 +3.34 kB 🔴 +982 B 🔴 +872 B
assets/subscriptionCheckoutUtil-C7GKpQpD.js (new) 3.31 kB 🔴 +3.31 kB 🔴 +1.36 kB 🔴 +1.19 kB
assets/subscriptionCheckoutUtil-F1Frs3x4.js (removed) 3.31 kB 🟢 -3.31 kB 🟢 -1.36 kB 🟢 -1.19 kB
assets/useExternalLink-B6p5Afrt.js (new) 3.03 kB 🔴 +3.03 kB 🔴 +1.16 kB 🔴 +1.02 kB
assets/useExternalLink-D4amNnkO.js (removed) 3.03 kB 🟢 -3.03 kB 🟢 -1.16 kB 🟢 -1.03 kB
assets/assetPreviewUtil-BD0OzF_h.js (new) 2.27 kB 🔴 +2.27 kB 🔴 +960 B 🔴 +832 B
assets/assetPreviewUtil-CHxxHfhr.js (removed) 2.27 kB 🟢 -2.27 kB 🟢 -958 B 🟢 -834 B
assets/useUpstreamValue-Biqbdxjg.js (new) 2.08 kB 🔴 +2.08 kB 🔴 +803 B 🔴 +709 B
assets/useUpstreamValue-CefOKvMb.js (removed) 2.08 kB 🟢 -2.08 kB 🟢 -804 B 🟢 -710 B
assets/useErrorHandling-DB3jDzhg.js (new) 1.54 kB 🔴 +1.54 kB 🔴 +649 B 🔴 +547 B
assets/useErrorHandling-Dxxas_Io.js (removed) 1.54 kB 🟢 -1.54 kB 🟢 -648 B 🟢 -548 B
assets/useLoad3d-4eJtr9UF.js (new) 1.3 kB 🔴 +1.3 kB 🔴 +607 B 🔴 +554 B
assets/useLoad3d-6Az7lg8B.js (removed) 1.3 kB 🟢 -1.3 kB 🟢 -603 B 🟢 -557 B
assets/useLoad3dViewer-B7Ha9XR9.js (removed) 1.24 kB 🟢 -1.24 kB 🟢 -572 B 🟢 -515 B
assets/useLoad3dViewer-YSttfbxP.js (new) 1.24 kB 🔴 +1.24 kB 🔴 +572 B 🔴 +513 B
assets/useCurrentUser-BZyPrYP9.js (removed) 1.12 kB 🟢 -1.12 kB 🟢 -539 B 🟢 -479 B
assets/useCurrentUser-CdM5lcd-.js (new) 1.12 kB 🔴 +1.12 kB 🔴 +540 B 🔴 +478 B
assets/useWorkspaceSwitch-BE64lT15.js (new) 747 B 🔴 +747 B 🔴 +385 B 🔴 +333 B
assets/useWorkspaceSwitch-CsEfzW52.js (removed) 747 B 🟢 -747 B 🟢 -383 B 🟢 -330 B

Status: 16 added / 16 removed / 15 unchanged

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

External libraries and shared vendor chunks

Status: 16 unchanged

Other — 8.83 MB (baseline 8.83 MB) • 🔴 +1.45 kB

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/i18n-CpxVPO34.js (new) 592 kB 🔴 +592 kB 🔴 +116 kB 🔴 +90.4 kB
assets/i18n-JCLqmYjf.js (removed) 590 kB 🟢 -590 kB 🟢 -115 kB 🟢 -90.1 kB
assets/core-BIQwNcRP.js (removed) 76.6 kB 🟢 -76.6 kB 🟢 -19.8 kB 🟢 -16.9 kB
assets/core-D0LSw9B7.js (new) 76.6 kB 🔴 +76.6 kB 🔴 +19.8 kB 🔴 +16.9 kB
assets/groupNode-4TTSUyeZ.js (removed) 74.9 kB 🟢 -74.9 kB 🟢 -18.7 kB 🟢 -16.5 kB
assets/groupNode-8EosI9y4.js (new) 74.9 kB 🔴 +74.9 kB 🔴 +18.7 kB 🔴 +16.5 kB
assets/WidgetSelect-D0xBa1-Q.js (new) 67.2 kB 🔴 +67.2 kB 🔴 +14.6 kB 🔴 +12.7 kB
assets/WidgetSelect-pkrlrB4h.js (removed) 67.2 kB 🟢 -67.2 kB 🟢 -14.6 kB 🟢 -12.6 kB
assets/SubscriptionRequiredDialogContentWorkspace-BVlskmhK.js (removed) 49.3 kB 🟢 -49.3 kB 🟢 -9.42 kB 🟢 -8.03 kB
assets/SubscriptionRequiredDialogContentWorkspace-cq4Ic5Rv.js (new) 49.3 kB 🔴 +49.3 kB 🔴 +9.42 kB 🔴 +8.06 kB
assets/Load3DControls-DF10YpYs.js (removed) 46.1 kB 🟢 -46.1 kB 🟢 -7.51 kB 🟢 -6.55 kB
assets/Load3DControls-DPHWSPop.js (new) 46.1 kB 🔴 +46.1 kB 🔴 +7.51 kB 🔴 +6.55 kB
assets/WidgetPainter-DNM3boPL.js (new) 34 kB 🔴 +34 kB 🔴 +8.29 kB 🔴 +7.34 kB
assets/WidgetPainter-o1DFEUJZ.js (removed) 34 kB 🟢 -34 kB 🟢 -8.28 kB 🟢 -7.34 kB
assets/WorkspacePanelContent-B1EMmWLe.js (new) 32.8 kB 🔴 +32.8 kB 🔴 +7 kB 🔴 +6.18 kB
assets/WorkspacePanelContent-Cz5Dw3fI.js (removed) 32.8 kB 🟢 -32.8 kB 🟢 -7 kB 🟢 -6.17 kB
assets/Load3dViewerContent-BopnYBaQ.js (new) 28 kB 🔴 +28 kB 🔴 +5.85 kB 🔴 +5.07 kB
assets/Load3dViewerContent-CkdPiKzg.js (removed) 28 kB 🟢 -28 kB 🟢 -5.85 kB 🟢 -5.08 kB
assets/SubscriptionRequiredDialogContent-DbMUzodQ.js (new) 27.5 kB 🔴 +27.5 kB 🔴 +6.96 kB 🔴 +6.18 kB
assets/SubscriptionRequiredDialogContent-goKHcOnO.js (removed) 27.5 kB 🟢 -27.5 kB 🟢 -6.96 kB 🟢 -6.15 kB
assets/WidgetImageCrop-BKbCF8Q3.js (new) 24.3 kB 🔴 +24.3 kB 🔴 +6.18 kB 🔴 +5.44 kB
assets/WidgetImageCrop-CMsdPff_.js (removed) 24.3 kB 🟢 -24.3 kB 🟢 -6.18 kB 🟢 -5.45 kB
assets/SubscriptionPanelContentWorkspace-D4TJqjp4.js (removed) 22.2 kB 🟢 -22.2 kB 🟢 -5.18 kB 🟢 -4.57 kB
assets/SubscriptionPanelContentWorkspace-qDxr_XNr.js (new) 22.2 kB 🔴 +22.2 kB 🔴 +5.18 kB 🔴 +4.57 kB
assets/SignInContent-BDVWTOsC.js (new) 20.6 kB 🔴 +20.6 kB 🔴 +5.36 kB 🔴 +4.67 kB
assets/SignInContent-Bu6OD5E7.js (removed) 20.6 kB 🟢 -20.6 kB 🟢 -5.35 kB 🟢 -4.68 kB
assets/CurrentUserPopoverWorkspace-Cotk90bm.js (removed) 20.5 kB 🟢 -20.5 kB 🟢 -4.9 kB 🟢 -4.39 kB
assets/CurrentUserPopoverWorkspace-Cr0V_fge.js (new) 20.5 kB 🔴 +20.5 kB 🔴 +4.9 kB 🔴 +4.39 kB
assets/WidgetInputNumber-C7FOuo0b.js (new) 19.1 kB 🔴 +19.1 kB 🔴 +4.84 kB 🔴 +4.29 kB
assets/WidgetInputNumber-CJ9fNCjb.js (removed) 19.1 kB 🟢 -19.1 kB 🟢 -4.84 kB 🟢 -4.29 kB
assets/Load3D-CQ2y-eqL.js (new) 18.5 kB 🔴 +18.5 kB 🔴 +4.39 kB 🔴 +3.85 kB
assets/Load3D-hYZGi_da.js (removed) 18.5 kB 🟢 -18.5 kB 🟢 -4.39 kB 🟢 -3.83 kB
assets/WidgetRecordAudio-BW9fKCmw.js (new) 17.4 kB 🔴 +17.4 kB 🔴 +5 kB 🔴 +4.47 kB
assets/WidgetRecordAudio-DIP_j7qf.js (removed) 17.4 kB 🟢 -17.4 kB 🟢 -5 kB 🟢 -4.47 kB
assets/WidgetRange-DTVhiwzp.js (removed) 17 kB 🟢 -17 kB 🟢 -4.59 kB 🟢 -4.11 kB
assets/WidgetRange-ggUkn9OG.js (new) 17 kB 🔴 +17 kB 🔴 +4.6 kB 🔴 +4.1 kB
assets/load3d-BmFI31-_.js (new) 15.7 kB 🔴 +15.7 kB 🔴 +4.57 kB 🔴 +3.94 kB
assets/load3d-DSy8snio.js (removed) 15.7 kB 🟢 -15.7 kB 🟢 -4.56 kB 🟢 -3.94 kB
assets/WaveAudioPlayer-f8Few5om.js (new) 13.4 kB 🔴 +13.4 kB 🔴 +3.69 kB 🔴 +3.23 kB
assets/WaveAudioPlayer-uULiO-Rc.js (removed) 13.4 kB 🟢 -13.4 kB 🟢 -3.69 kB 🟢 -3.23 kB
assets/WidgetCurve-CbceD7Io.js (removed) 12.1 kB 🟢 -12.1 kB 🟢 -3.91 kB 🟢 -3.54 kB
assets/WidgetCurve-CWzEwxGh.js (new) 12.1 kB 🔴 +12.1 kB 🔴 +3.91 kB 🔴 +3.55 kB
assets/TeamWorkspacesDialogContent-833ZTZH-.js (new) 11.3 kB 🔴 +11.3 kB 🔴 +3.41 kB 🔴 +3.04 kB
assets/TeamWorkspacesDialogContent-D3-4czLH.js (removed) 11.3 kB 🟢 -11.3 kB 🟢 -3.41 kB 🟢 -3.03 kB
assets/AudioPreviewPlayer-BrR02ezj.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -3.13 kB 🟢 -2.8 kB
assets/AudioPreviewPlayer-CoE0JqQH.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +3.13 kB 🔴 +2.81 kB
assets/nodeTemplates-CN1NXSD3.js (new) 9.81 kB 🔴 +9.81 kB 🔴 +3.47 kB 🔴 +3.06 kB
assets/nodeTemplates-D1ReIz5z.js (removed) 9.81 kB 🟢 -9.81 kB 🟢 -3.47 kB 🟢 -3.06 kB
assets/NightlySurveyController-BckPn_ud.js (new) 8.99 kB 🔴 +8.99 kB 🔴 +3.15 kB 🔴 +2.78 kB
assets/NightlySurveyController-DCLXgxHR.js (removed) 8.99 kB 🟢 -8.99 kB 🟢 -3.15 kB 🟢 -2.78 kB
assets/InviteMemberDialogContent-2Sh7pNFf.js (removed) 7.91 kB 🟢 -7.91 kB 🟢 -2.51 kB 🟢 -2.21 kB
assets/InviteMemberDialogContent-OSHKL5d7.js (new) 7.91 kB 🔴 +7.91 kB 🔴 +2.51 kB 🔴 +2.21 kB
assets/Load3DConfiguration-CebtDaWM.js (removed) 7.82 kB 🟢 -7.82 kB 🟢 -2.31 kB 🟢 -2.02 kB
assets/Load3DConfiguration-CLuoyQ2-.js (new) 7.82 kB 🔴 +7.82 kB 🔴 +2.31 kB 🔴 +2.02 kB
assets/onboardingCloudRoutes-B5qCnHXL.js (removed) 6.58 kB 🟢 -6.58 kB 🟢 -2.05 kB 🟢 -1.76 kB
assets/onboardingCloudRoutes-DGPktX23.js (new) 6.58 kB 🔴 +6.58 kB 🔴 +2.05 kB 🔴 +1.76 kB
assets/CreateWorkspaceDialogContent-BSSTTq6B.js (new) 6.12 kB 🔴 +6.12 kB 🔴 +2.22 kB 🔴 +1.95 kB
assets/CreateWorkspaceDialogContent-CLG5KNwD.js (removed) 6.12 kB 🟢 -6.12 kB 🟢 -2.22 kB 🟢 -1.95 kB
assets/WidgetWithControl-BM9hrKcR.js (new) 6.02 kB 🔴 +6.02 kB 🔴 +2.4 kB 🔴 +2.15 kB
assets/WidgetWithControl-DRMkjgBa.js (removed) 6.02 kB 🟢 -6.02 kB 🟢 -2.4 kB 🟢 -2.15 kB
assets/FreeTierDialogContent-Cl1795Wi.js (removed) 5.99 kB 🟢 -5.99 kB 🟢 -2.12 kB 🟢 -1.87 kB
assets/FreeTierDialogContent-CygO6ulN.js (new) 5.99 kB 🔴 +5.99 kB 🔴 +2.12 kB 🔴 +1.88 kB
assets/EditWorkspaceDialogContent-B-myFo5g.js (new) 5.92 kB 🔴 +5.92 kB 🔴 +2.19 kB 🔴 +1.93 kB
assets/EditWorkspaceDialogContent-C2zErDOf.js (removed) 5.92 kB 🟢 -5.92 kB 🟢 -2.18 kB 🟢 -1.91 kB
assets/WidgetTextarea-D-AXhz9W.js (new) 5.73 kB 🔴 +5.73 kB 🔴 +2.26 kB 🔴 +2 kB
assets/WidgetTextarea-wCBjFOoR.js (removed) 5.73 kB 🟢 -5.73 kB 🟢 -2.26 kB 🟢 -2 kB
assets/Preview3d-B_hA_3ys.js (removed) 5.7 kB 🟢 -5.7 kB 🟢 -1.91 kB 🟢 -1.67 kB
assets/Preview3d-Ba_nLuaq.js (new) 5.7 kB 🔴 +5.7 kB 🔴 +1.91 kB 🔴 +1.66 kB
assets/ValueControlPopover-CXY4B-Km.js (removed) 5.5 kB 🟢 -5.5 kB 🟢 -2 kB 🟢 -1.78 kB
assets/ValueControlPopover-DMDlt0sY.js (new) 5.5 kB 🔴 +5.5 kB 🔴 +2 kB 🔴 +1.79 kB
assets/CancelSubscriptionDialogContent-CHmza0WK.js (new) 5.46 kB 🔴 +5.46 kB 🔴 +2.04 kB 🔴 +1.79 kB
assets/CancelSubscriptionDialogContent-DIcdyqmU.js (removed) 5.46 kB 🟢 -5.46 kB 🟢 -2.04 kB 🟢 -1.79 kB
assets/DeleteWorkspaceDialogContent-CxXSnJgC.js (new) 4.82 kB 🔴 +4.82 kB 🔴 +1.86 kB 🔴 +1.62 kB
assets/DeleteWorkspaceDialogContent-D1XFPO5R.js (removed) 4.82 kB 🟢 -4.82 kB 🟢 -1.86 kB 🟢 -1.61 kB
assets/LeaveWorkspaceDialogContent-Bs_8vopf.js (removed) 4.65 kB 🟢 -4.65 kB 🟢 -1.8 kB 🟢 -1.58 kB
assets/LeaveWorkspaceDialogContent-BST-uQxA.js (new) 4.65 kB 🔴 +4.65 kB 🔴 +1.81 kB 🔴 +1.57 kB
assets/RemoveMemberDialogContent-CBEr7mv7.js (new) 4.63 kB 🔴 +4.63 kB 🔴 +1.76 kB 🔴 +1.55 kB
assets/RemoveMemberDialogContent-G416K0d8.js (removed) 4.63 kB 🟢 -4.63 kB 🟢 -1.76 kB 🟢 -1.54 kB
assets/RevokeInviteDialogContent-DWshdWcn.js (new) 4.54 kB 🔴 +4.54 kB 🔴 +1.77 kB 🔴 +1.55 kB
assets/RevokeInviteDialogContent-iBL6vRBn.js (removed) 4.54 kB 🟢 -4.54 kB 🟢 -1.77 kB 🟢 -1.55 kB
assets/tierBenefits-B6c4Asjc.js (removed) 4.45 kB 🟢 -4.45 kB 🟢 -1.57 kB 🟢 -1.36 kB
assets/tierBenefits-D5RpvZPq.js (new) 4.45 kB 🔴 +4.45 kB 🔴 +1.58 kB 🔴 +1.36 kB
assets/InviteMemberUpsellDialogContent-BFLYPnCN.js (new) 4.44 kB 🔴 +4.44 kB 🔴 +1.64 kB 🔴 +1.44 kB
assets/InviteMemberUpsellDialogContent-DZFgMoCJ.js (removed) 4.44 kB 🟢 -4.44 kB 🟢 -1.64 kB 🟢 -1.44 kB
assets/cloudSessionCookie-Du-u4OVq.js (new) 4.28 kB 🔴 +4.28 kB 🔴 +1.56 kB 🔴 +1.36 kB
assets/cloudSessionCookie-n7kjm9Vp.js (removed) 4.28 kB 🟢 -4.28 kB 🟢 -1.56 kB 🟢 -1.36 kB
assets/ApiNodesSignInContent-Bsa0yQyx.js (removed) 4.26 kB 🟢 -4.26 kB 🟢 -1.4 kB 🟢 -1.23 kB
assets/ApiNodesSignInContent-BttW2bQ2.js (new) 4.26 kB 🔴 +4.26 kB 🔴 +1.4 kB 🔴 +1.23 kB
assets/Media3DTop-Bl5ouW7G.js (removed) 4.01 kB 🟢 -4.01 kB 🟢 -1.7 kB 🟢 -1.5 kB
assets/Media3DTop-DHxy1Srg.js (new) 4.01 kB 🔴 +4.01 kB 🔴 +1.7 kB 🔴 +1.5 kB
assets/saveMesh-BaNyKUTF.js (new) 3.98 kB 🔴 +3.98 kB 🔴 +1.73 kB 🔴 +1.54 kB
assets/saveMesh-qRR05lU0.js (removed) 3.98 kB 🟢 -3.98 kB 🟢 -1.73 kB 🟢 -1.53 kB
assets/GlobalToast-ClC016fI.js (removed) 3.05 kB 🟢 -3.05 kB 🟢 -1.26 kB 🟢 -1.11 kB
assets/GlobalToast-uanPClHY.js (new) 3.05 kB 🔴 +3.05 kB 🔴 +1.26 kB 🔴 +1.1 kB
assets/CloudRunButtonWrapper-C8pZqkhK.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -1 kB 🟢 -891 B
assets/CloudRunButtonWrapper-D7gkqGKg.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +1.01 kB 🔴 +895 B
assets/SubscribeToRun-B_Xaa4AR.js (new) 2.13 kB 🔴 +2.13 kB 🔴 +983 B 🔴 +880 B
assets/SubscribeToRun-CwotcDv0.js (removed) 2.13 kB 🟢 -2.13 kB 🟢 -982 B 🟢 -879 B
assets/MediaAudioTop-By0pWWLC.js (new) 2.08 kB 🔴 +2.08 kB 🔴 +1.01 kB 🔴 +860 B
assets/MediaAudioTop-Dj5_eH__.js (removed) 2.08 kB 🟢 -2.08 kB 🟢 -1.01 kB 🟢 -859 B
assets/cloudBadges-6owJffZ1.js (new) 1.93 kB 🔴 +1.93 kB 🔴 +962 B 🔴 +833 B
assets/cloudBadges-CpItlr35.js (removed) 1.93 kB 🟢 -1.93 kB 🟢 -961 B 🟢 -830 B
assets/cloudSubscription-BxClvok6.js (removed) 1.85 kB 🟢 -1.85 kB 🟢 -883 B 🟢 -780 B
assets/cloudSubscription-CR33A1V9.js (new) 1.85 kB 🔴 +1.85 kB 🔴 +885 B 🔴 +767 B
assets/graphHasMissingNodes-CxuMM0DN.js (removed) 1.84 kB 🟢 -1.84 kB 🟢 -861 B 🟢 -771 B
assets/graphHasMissingNodes-DxRPPhEV.js (new) 1.84 kB 🔴 +1.84 kB 🔴 +862 B 🔴 +775 B
assets/signInSchema-_LCGeall.js (removed) 1.6 kB 🟢 -1.6 kB 🟢 -585 B 🟢 -513 B
assets/signInSchema-Dbgj2GPL.js (new) 1.6 kB 🔴 +1.6 kB 🔴 +586 B 🔴 +512 B
assets/Load3D-DJwxw4Jn.js (removed) 1.55 kB 🟢 -1.55 kB 🟢 -695 B 🟢 -621 B
assets/Load3D-LQtRWoA7.js (new) 1.55 kB 🔴 +1.55 kB 🔴 +693 B 🔴 +620 B
assets/previousFullPath-CcZSa-4y.js (removed) 1.53 kB 🟢 -1.53 kB 🟢 -694 B 🟢 -592 B
assets/previousFullPath-D_2O6spJ.js (new) 1.53 kB 🔴 +1.53 kB 🔴 +695 B 🔴 +598 B
assets/nightlyBadges-BG9JXBEq.js (new) 1.46 kB 🔴 +1.46 kB 🔴 +736 B 🔴 +670 B
assets/nightlyBadges-C1FQiAOw.js (removed) 1.46 kB 🟢 -1.46 kB 🟢 -732 B 🟢 -661 B
assets/Load3dViewerContent-B1FHdwcV.js (new) 1.43 kB 🔴 +1.43 kB 🔴 +649 B 🔴 +590 B
assets/Load3dViewerContent-B5xa-0yD.js (removed) 1.43 kB 🟢 -1.43 kB 🟢 -649 B 🟢 -591 B
assets/SubscriptionPanelContentWorkspace-aUIczpQh.js (new) 1.32 kB 🔴 +1.32 kB 🔴 +604 B 🔴 +524 B
assets/SubscriptionPanelContentWorkspace-BUXnnbOi.js (removed) 1.32 kB 🟢 -1.32 kB 🟢 -602 B 🟢 -524 B
assets/WidgetLegacy-BABAgH23.js (new) 1.15 kB 🔴 +1.15 kB 🔴 +552 B 🔴 +487 B
assets/WidgetLegacy-BHgWJAM0.js (removed) 1.15 kB 🟢 -1.15 kB 🟢 -550 B 🟢 -484 B
assets/changeTracker-BdV8hfRP.js (new) 1.12 kB 🔴 +1.12 kB 🔴 +540 B 🔴 +469 B
assets/changeTracker-D4QQTvOX.js (removed) 1.12 kB 🟢 -1.12 kB 🟢 -539 B 🟢 -470 B
assets/i18n-CoF0YLz6.js (removed) 137 B 🟢 -137 B 🟢 -122 B 🟢 -110 B
assets/i18n-d7eJMARD.js (new) 137 B 🔴 +137 B 🔴 +122 B 🔴 +109 B

Status: 62 added / 62 removed / 73 unchanged

⚡ Performance Report

canvas-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 68.0 MB heap
canvas-mouse-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 46.9 MB heap
canvas-zoom-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 46.3 MB heap
dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 54.7 MB heap
large-graph-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 57.4 MB heap
large-graph-pan: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 55.7 MB heap
large-graph-zoom: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 66.8 MB heap
minimap-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 62.5 MB heap
subgraph-dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 55.2 MB heap
subgraph-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 68.4 MB heap
subgraph-mouse-sweep: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 59.4 MB heap
viewport-pan-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 65.9 MB heap
vue-large-graph-idle: · 58.1 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 165.0 MB heap
vue-large-graph-pan: · 58.1 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 83ms TBT · 157.5 MB heap
workflow-execution: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 52.6 MB heap

⚠️ 4 regressions detected

Metric Baseline PR (median) Δ Sig
large-graph-idle: task duration 553ms 695ms +26% ⚠️ z=2.8
large-graph-pan: task duration 1058ms 1208ms +14% ⚠️ z=2.9
minimap-idle: task duration 542ms 674ms +24% ⚠️ z=3.1
subgraph-idle: task duration 352ms 433ms +23% ⚠️ z=2.0
All metrics
Metric Baseline PR (median) Δ Sig
canvas-idle: avg frame time 17ms 17ms +0% z=-0.1
canvas-idle: p95 frame time 17ms 17ms +0%
canvas-idle: layout duration 0ms 0ms +0%
canvas-idle: style recalc duration 7ms 9ms +24% z=-2.2
canvas-idle: layout count 0 0 +0%
canvas-idle: style recalc count 8 8 +0% z=-5.6
canvas-idle: task duration 364ms 427ms +17% z=1.0
canvas-idle: script duration 18ms 24ms +32% z=-0.8
canvas-idle: TBT 0ms 0ms +0%
canvas-idle: heap used 67.7 MB 68.0 MB +1%
canvas-idle: DOM nodes 16 16 +0% z=-5.2
canvas-idle: event listeners 4 4 +0% z=-1.6
canvas-mouse-sweep: avg frame time 17ms 17ms +0% z=-0.4
canvas-mouse-sweep: p95 frame time 17ms 17ms +0%
canvas-mouse-sweep: layout duration 4ms 3ms -12% z=-1.5
canvas-mouse-sweep: style recalc duration 42ms 39ms -6% z=-1.1
canvas-mouse-sweep: layout count 12 12 +0%
canvas-mouse-sweep: style recalc count 76 71 -7% z=-3.3
canvas-mouse-sweep: task duration 903ms 870ms -4% z=0.1
canvas-mouse-sweep: script duration 129ms 136ms +6% z=0.1
canvas-mouse-sweep: TBT 0ms 0ms +0%
canvas-mouse-sweep: heap used 47.0 MB 46.9 MB -0%
canvas-mouse-sweep: DOM nodes -264 -265 +0% z=-126.5
canvas-mouse-sweep: event listeners -131 -131 +0% z=-33.5
canvas-zoom-sweep: avg frame time 17ms 17ms +0% z=0.5
canvas-zoom-sweep: p95 frame time 17ms 17ms +0%
canvas-zoom-sweep: layout duration 1ms 1ms -11% z=-0.5
canvas-zoom-sweep: style recalc duration 19ms 20ms +6% z=0.5
canvas-zoom-sweep: layout count 6 6 +0%
canvas-zoom-sweep: style recalc count 32 33 +3% z=3.8
canvas-zoom-sweep: task duration 305ms 372ms +22% z=1.9
canvas-zoom-sweep: script duration 20ms 28ms +40% z=0.3
canvas-zoom-sweep: TBT 0ms 0ms +0%
canvas-zoom-sweep: heap used 46.4 MB 46.3 MB -0%
canvas-zoom-sweep: DOM nodes 77 78 +1% 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 8ms 7ms -11% z=-3.7
dom-widget-clipping: layout count 0 0 +0%
dom-widget-clipping: style recalc count 12 9 -25% z=-8.3
dom-widget-clipping: task duration 340ms 356ms +5% z=-0.5
dom-widget-clipping: script duration 64ms 63ms -1% z=-1.5
dom-widget-clipping: TBT 0ms 0ms +0%
dom-widget-clipping: heap used 55.0 MB 54.7 MB -1%
dom-widget-clipping: DOM nodes 20 14 -30% z=-5.7
dom-widget-clipping: event listeners 2 0 -100% variance too high
large-graph-idle: avg frame time 17ms 17ms +0% z=-0.2
large-graph-idle: p95 frame time 17ms 17ms +1%
large-graph-idle: layout duration 0ms 0ms +0%
large-graph-idle: style recalc duration 8ms 9ms +11% z=-3.3
large-graph-idle: layout count 0 0 +0%
large-graph-idle: style recalc count 8 8 +0% z=-11.5
large-graph-idle: task duration 553ms 695ms +26% ⚠️ z=2.8
large-graph-idle: script duration 88ms 114ms +30% z=1.1
large-graph-idle: TBT 0ms 0ms +0%
large-graph-idle: heap used 65.0 MB 57.4 MB -12%
large-graph-idle: DOM nodes -263 -265 +1% z=-320.5
large-graph-idle: event listeners -127 -125 -2% z=-24.8
large-graph-pan: avg frame time 17ms 17ms -0% z=-0.8
large-graph-pan: p95 frame time 17ms 17ms +0%
large-graph-pan: layout duration 0ms 0ms +0%
large-graph-pan: style recalc duration 18ms 19ms +4% z=1.6
large-graph-pan: layout count 0 0 +0%
large-graph-pan: style recalc count 67 68 +1% z=-2.4
large-graph-pan: task duration 1058ms 1208ms +14% ⚠️ z=2.9
large-graph-pan: script duration 371ms 423ms +14% z=0.7
large-graph-pan: TBT 0ms 0ms +0%
large-graph-pan: heap used 58.5 MB 55.7 MB -5%
large-graph-pan: DOM nodes -265 -267 +1% z=-173.3
large-graph-pan: event listeners -125 -127 +2% z=-159.3
large-graph-zoom: avg frame time 17ms 17ms +0%
large-graph-zoom: p95 frame time 17ms 17ms +1%
large-graph-zoom: layout duration 8ms 8ms -7%
large-graph-zoom: style recalc duration 20ms 19ms -4%
large-graph-zoom: layout count 60 60 +0%
large-graph-zoom: style recalc count 65 65 +0%
large-graph-zoom: task duration 1322ms 1481ms +12%
large-graph-zoom: script duration 496ms 541ms +9%
large-graph-zoom: TBT 0ms 0ms +0%
large-graph-zoom: heap used 72.2 MB 66.8 MB -8%
large-graph-zoom: DOM nodes -269 -271 +1%
large-graph-zoom: event listeners -155 -123 -21%
minimap-idle: avg frame time 17ms 17ms +0% z=0.1
minimap-idle: p95 frame time 17ms 17ms -1%
minimap-idle: layout duration 0ms 0ms +0%
minimap-idle: style recalc duration 7ms 10ms +40% z=0.5
minimap-idle: layout count 0 0 +0%
minimap-idle: style recalc count 8 8 +0% z=-2.3
minimap-idle: task duration 542ms 674ms +24% ⚠️ z=3.1
minimap-idle: script duration 88ms 111ms +26% z=1.3
minimap-idle: TBT 0ms 0ms +0%
minimap-idle: heap used 61.8 MB 62.5 MB +1%
minimap-idle: DOM nodes -265 -266 +0% z=-208.5
minimap-idle: event listeners -127 -125 -2% z=-196.2
subgraph-dom-widget-clipping: avg frame time 17ms 17ms +0% z=0.1
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 11ms 11ms +5% z=-1.8
subgraph-dom-widget-clipping: layout count 0 0 +0%
subgraph-dom-widget-clipping: style recalc count 46 45 -2% z=-5.0
subgraph-dom-widget-clipping: task duration 351ms 391ms +11% z=0.7
subgraph-dom-widget-clipping: script duration 121ms 128ms +6% z=-0.0
subgraph-dom-widget-clipping: TBT 0ms 0ms +0%
subgraph-dom-widget-clipping: heap used 55.1 MB 55.2 MB +0%
subgraph-dom-widget-clipping: DOM nodes 18 16 -11% z=-5.5
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 8ms 10ms +18% z=-1.0
subgraph-idle: layout count 0 0 +0%
subgraph-idle: style recalc count 9 9 +0% z=-2.9
subgraph-idle: task duration 352ms 433ms +23% ⚠️ z=2.0
subgraph-idle: script duration 16ms 22ms +43% z=0.8
subgraph-idle: TBT 0ms 0ms +0%
subgraph-idle: heap used 67.7 MB 68.4 MB +1%
subgraph-idle: DOM nodes 18 18 +0% z=-2.5
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 +1%
subgraph-mouse-sweep: layout duration 5ms 5ms -2% z=-0.6
subgraph-mouse-sweep: style recalc duration 38ms 40ms +6% z=-0.6
subgraph-mouse-sweep: layout count 16 16 +0%
subgraph-mouse-sweep: style recalc count 76 75 -1% z=-2.7
subgraph-mouse-sweep: task duration 691ms 764ms +11% z=-0.0
subgraph-mouse-sweep: script duration 94ms 107ms +14% z=1.0
subgraph-mouse-sweep: TBT 0ms 0ms +0%
subgraph-mouse-sweep: heap used 44.4 MB 59.4 MB +34%
subgraph-mouse-sweep: DOM nodes -262 60 -123% z=-3.1
subgraph-mouse-sweep: event listeners -131 4 -103% variance too high
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 57ms 54ms -4%
viewport-pan-sweep: layout count 0 0 +0%
viewport-pan-sweep: style recalc count 249 250 +0%
viewport-pan-sweep: task duration 3775ms 4191ms +11%
viewport-pan-sweep: script duration 1297ms 1381ms +6%
viewport-pan-sweep: TBT 0ms 0ms +0%
viewport-pan-sweep: heap used 69.6 MB 65.9 MB -5%
viewport-pan-sweep: DOM nodes -264 -263 -0%
viewport-pan-sweep: event listeners -111 -111 +0%
vue-large-graph-idle: avg frame time 18ms 17ms -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 13236ms 12967ms -2%
vue-large-graph-idle: script duration 627ms 634ms +1%
vue-large-graph-idle: TBT 0ms 0ms +0%
vue-large-graph-idle: heap used 164.6 MB 165.0 MB +0%
vue-large-graph-idle: DOM nodes -9850 -9850 +0%
vue-large-graph-idle: event listeners -23955 -23957 +0%
vue-large-graph-pan: avg frame time 18ms 17ms -3%
vue-large-graph-pan: p95 frame time 17ms 17ms +1%
vue-large-graph-pan: layout duration 0ms 0ms +0%
vue-large-graph-pan: style recalc duration 20ms 19ms -7%
vue-large-graph-pan: layout count 0 0 +0%
vue-large-graph-pan: style recalc count 73 68 -7%
vue-large-graph-pan: task duration 15354ms 14863ms -3%
vue-large-graph-pan: script duration 882ms 968ms +10%
vue-large-graph-pan: TBT 0ms 83ms
vue-large-graph-pan: heap used 162.6 MB 157.5 MB -3%
vue-large-graph-pan: DOM nodes -9850 -9850 +0%
vue-large-graph-pan: event listeners -23954 -23983 +0%
workflow-execution: avg frame time 17ms 17ms +0% z=0.6
workflow-execution: p95 frame time 17ms 17ms +0%
workflow-execution: layout duration 1ms 2ms +5% z=-0.2
workflow-execution: style recalc duration 23ms 25ms +8% z=0.5
workflow-execution: layout count 5 5 +0% z=0.1
workflow-execution: style recalc count 17 18 +6% z=0.1
workflow-execution: task duration 124ms 126ms +1% z=0.3
workflow-execution: script duration 27ms 26ms -4% z=-0.9
workflow-execution: TBT 0ms 0ms +0%
workflow-execution: heap used 52.7 MB 52.6 MB -0%
workflow-execution: DOM nodes 156 167 +7% z=0.9
workflow-execution: event listeners 69 69 +0% z=3.9
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-04-30T08:55:38.306Z",
  "gitSha": "8f66b16065329b1e00e5b92ae3c3c836092fefcc",
  "branch": "jaewon/fe-480-fix-unsupported-locale",
  "measurements": [
    {
      "name": "canvas-idle",
      "durationMs": 2015.7899999999813,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 7.997999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 386.966,
      "heapDeltaBytes": 23096228,
      "heapUsedBytes": 71338860,
      "domNodes": 16,
      "jsHeapTotalBytes": 15204352,
      "scriptDurationMs": 20.40500000000001,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-idle",
      "durationMs": 2015.0820000000067,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 9.912999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 451.93799999999993,
      "heapDeltaBytes": 22714180,
      "heapUsedBytes": 70981144,
      "domNodes": 18,
      "jsHeapTotalBytes": 14680064,
      "scriptDurationMs": 25.536,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-idle",
      "durationMs": 2017.9620000000114,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 8.864999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 427.07000000000005,
      "heapDeltaBytes": 22888548,
      "heapUsedBytes": 71521156,
      "domNodes": 16,
      "jsHeapTotalBytes": 14680064,
      "scriptDurationMs": 23.515,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1853.4049999999809,
      "styleRecalcs": 71,
      "styleRecalcDurationMs": 46.858000000000004,
      "layouts": 12,
      "layoutDurationMs": 3.194,
      "taskDurationMs": 875.8229999999999,
      "heapDeltaBytes": 907712,
      "heapUsedBytes": 49202408,
      "domNodes": -265,
      "jsHeapTotalBytes": 15069184,
      "scriptDurationMs": 137.757,
      "eventListeners": -131,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1848.747000000003,
      "styleRecalcs": 71,
      "styleRecalcDurationMs": 36.263999999999996,
      "layouts": 12,
      "layoutDurationMs": 3.3149999999999995,
      "taskDurationMs": 856.3599999999999,
      "heapDeltaBytes": -1069792,
      "heapUsedBytes": 47283188,
      "domNodes": -265,
      "jsHeapTotalBytes": 15593472,
      "scriptDurationMs": 136.34799999999998,
      "eventListeners": -131,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-mouse-sweep",
      "durationMs": 1884.2129999999315,
      "styleRecalcs": 72,
      "styleRecalcDurationMs": 39.099999999999994,
      "layouts": 12,
      "layoutDurationMs": 3.683,
      "taskDurationMs": 869.518,
      "heapDeltaBytes": 5022964,
      "heapUsedBytes": 53701500,
      "domNodes": -265,
      "jsHeapTotalBytes": 16379904,
      "scriptDurationMs": 136.343,
      "eventListeners": -131,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1746.155999999985,
      "styleRecalcs": 33,
      "styleRecalcDurationMs": 19.617999999999995,
      "layouts": 6,
      "layoutDurationMs": 0.551,
      "taskDurationMs": 371.61299999999994,
      "heapDeltaBytes": 298916,
      "heapUsedBytes": 49076892,
      "domNodes": 79,
      "jsHeapTotalBytes": 15204352,
      "scriptDurationMs": 33.749,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1754.1629999999486,
      "styleRecalcs": 33,
      "styleRecalcDurationMs": 20.136999999999997,
      "layouts": 6,
      "layoutDurationMs": 0.621,
      "taskDurationMs": 376.116,
      "heapDeltaBytes": 215748,
      "heapUsedBytes": 48501128,
      "domNodes": 78,
      "jsHeapTotalBytes": 14680064,
      "scriptDurationMs": 28.072,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "canvas-zoom-sweep",
      "durationMs": 1751.7540000000054,
      "styleRecalcs": 31,
      "styleRecalcDurationMs": 19.883000000000006,
      "layouts": 6,
      "layoutDurationMs": 0.7800000000000001,
      "taskDurationMs": 365.244,
      "heapDeltaBytes": 210876,
      "heapUsedBytes": 48543048,
      "domNodes": 75,
      "jsHeapTotalBytes": 14417920,
      "scriptDurationMs": 26.341000000000005,
      "eventListeners": 19,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 682.1150000000102,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 6.944999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 412.40900000000005,
      "heapDeltaBytes": 9110632,
      "heapUsedBytes": 57406440,
      "domNodes": 12,
      "jsHeapTotalBytes": 15204352,
      "scriptDurationMs": 75.34700000000001,
      "eventListeners": 2,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 575.396000000012,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 6.485000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 346.334,
      "heapDeltaBytes": 9424152,
      "heapUsedBytes": 57340436,
      "domNodes": 14,
      "jsHeapTotalBytes": 15728640,
      "scriptDurationMs": 61.07099999999999,
      "eventListeners": 0,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "dom-widget-clipping",
      "durationMs": 572.8320000000622,
      "styleRecalcs": 10,
      "styleRecalcDurationMs": 7.303000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 355.9939999999999,
      "heapDeltaBytes": 8827416,
      "heapUsedBytes": 56828716,
      "domNodes": 16,
      "jsHeapTotalBytes": 14417920,
      "scriptDurationMs": 63.019999999999996,
      "eventListeners": 0,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.669999999999998,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2030.9929999999667,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 8.806999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 702.0260000000001,
      "heapDeltaBytes": 1849528,
      "heapUsedBytes": 60113904,
      "domNodes": -265,
      "jsHeapTotalBytes": 5013504,
      "scriptDurationMs": 114.37000000000002,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2033.3210000000008,
      "styleRecalcs": 7,
      "styleRecalcDurationMs": 8.358999999999998,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 682.3000000000001,
      "heapDeltaBytes": 1659308,
      "heapUsedBytes": 60194904,
      "domNodes": -267,
      "jsHeapTotalBytes": 5799936,
      "scriptDurationMs": 113.34700000000001,
      "eventListeners": -125,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "large-graph-idle",
      "durationMs": 2040.04000000009,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 10.468000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 694.5669999999999,
      "heapDeltaBytes": 13460056,
      "heapUsedBytes": 70348688,
      "domNodes": -260,
      "jsHeapTotalBytes": -753664,
      "scriptDurationMs": 122.12599999999999,
      "eventListeners": -125,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2134.736999999973,
      "styleRecalcs": 68,
      "styleRecalcDurationMs": 18.772000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1208.4279999999999,
      "heapDeltaBytes": -1376684,
      "heapUsedBytes": 58096184,
      "domNodes": -267,
      "jsHeapTotalBytes": 761856,
      "scriptDurationMs": 421.918,
      "eventListeners": -125,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2165.4189999999858,
      "styleRecalcs": 67,
      "styleRecalcDurationMs": 18.392000000000003,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1276.0240000000001,
      "heapDeltaBytes": 9598168,
      "heapUsedBytes": 69139452,
      "domNodes": -269,
      "jsHeapTotalBytes": -24576,
      "scriptDurationMs": 453.22799999999995,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333335,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "large-graph-pan",
      "durationMs": 2129.7309999999925,
      "styleRecalcs": 68,
      "styleRecalcDurationMs": 18.583000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 1206.055,
      "heapDeltaBytes": -864920,
      "heapUsedBytes": 58443096,
      "domNodes": -265,
      "jsHeapTotalBytes": 761856,
      "scriptDurationMs": 422.531,
      "eventListeners": -127,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3200.4230000000007,
      "styleRecalcs": 65,
      "styleRecalcDurationMs": 19.156999999999996,
      "layouts": 60,
      "layoutDurationMs": 7.7250000000000005,
      "taskDurationMs": 1484.969,
      "heapDeltaBytes": 15018332,
      "heapUsedBytes": 76005724,
      "domNodes": -271,
      "jsHeapTotalBytes": -491520,
      "scriptDurationMs": 540.79,
      "eventListeners": -125,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3212.1099999999956,
      "styleRecalcs": 65,
      "styleRecalcDurationMs": 20.039999999999996,
      "layouts": 60,
      "layoutDurationMs": 7.808000000000001,
      "taskDurationMs": 1480.5070000000003,
      "heapDeltaBytes": 9136472,
      "heapUsedBytes": 70035260,
      "domNodes": -269,
      "jsHeapTotalBytes": 4751360,
      "scriptDurationMs": 540.8219999999999,
      "eventListeners": -123,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "large-graph-zoom",
      "durationMs": 3198.8509999999906,
      "styleRecalcs": 64,
      "styleRecalcDurationMs": 18.94,
      "layouts": 60,
      "layoutDurationMs": 7.8919999999999995,
      "taskDurationMs": 1466.608,
      "heapDeltaBytes": 8080972,
      "heapUsedBytes": 69133240,
      "domNodes": -271,
      "jsHeapTotalBytes": 5799936,
      "scriptDurationMs": 535.988,
      "eventListeners": -123,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "minimap-idle",
      "durationMs": 2016.6430000000446,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 10.041000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 673.9999999999999,
      "heapDeltaBytes": 6027344,
      "heapUsedBytes": 65533876,
      "domNodes": -266,
      "jsHeapTotalBytes": 557056,
      "scriptDurationMs": 111.299,
      "eventListeners": -125,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "minimap-idle",
      "durationMs": 2008.1390000000283,
      "styleRecalcs": 6,
      "styleRecalcDurationMs": 6.532,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 677.856,
      "heapDeltaBytes": 925196,
      "heapUsedBytes": 60661268,
      "domNodes": -272,
      "jsHeapTotalBytes": 4227072,
      "scriptDurationMs": 112.428,
      "eventListeners": -157,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "minimap-idle",
      "durationMs": 2050.2539999999954,
      "styleRecalcs": 8,
      "styleRecalcDurationMs": 9.949,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 664.156,
      "heapDeltaBytes": 14985772,
      "heapUsedBytes": 75403228,
      "domNodes": -260,
      "jsHeapTotalBytes": -229376,
      "scriptDurationMs": 109.597,
      "eventListeners": -125,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 583.4169999999972,
      "styleRecalcs": 45,
      "styleRecalcDurationMs": 11.033000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 378.935,
      "heapDeltaBytes": 9399484,
      "heapUsedBytes": 58032528,
      "domNodes": 16,
      "jsHeapTotalBytes": 14942208,
      "scriptDurationMs": 126.76300000000002,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666682,
      "p95FrameDurationMs": 16.799999999999727
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 587.5929999999698,
      "styleRecalcs": 47,
      "styleRecalcDurationMs": 12.648,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 391.15,
      "heapDeltaBytes": 9098336,
      "heapUsedBytes": 57847684,
      "domNodes": 19,
      "jsHeapTotalBytes": 15204352,
      "scriptDurationMs": 128.079,
      "eventListeners": 6,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66666666666665,
      "p95FrameDurationMs": 16.700000000000273
    },
    {
      "name": "subgraph-dom-widget-clipping",
      "durationMs": 616.7960000000221,
      "styleRecalcs": 45,
      "styleRecalcDurationMs": 10.985000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 407.91900000000004,
      "heapDeltaBytes": 8821724,
      "heapUsedBytes": 57425780,
      "domNodes": 16,
      "jsHeapTotalBytes": 15990784,
      "scriptDurationMs": 135.01399999999998,
      "eventListeners": 8,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66999999999998,
      "p95FrameDurationMs": 16.700000000000273
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2021.2329999999952,
      "styleRecalcs": 11,
      "styleRecalcDurationMs": 11.665,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 471.473,
      "heapDeltaBytes": 23306764,
      "heapUsedBytes": 71735332,
      "domNodes": 21,
      "jsHeapTotalBytes": 14942208,
      "scriptDurationMs": 33.522,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2005.4420000000164,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 9.414000000000001,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 429.61499999999995,
      "heapDeltaBytes": 22190196,
      "heapUsedBytes": 71820080,
      "domNodes": 18,
      "jsHeapTotalBytes": 15204352,
      "scriptDurationMs": 22.311,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-idle",
      "durationMs": 2006.4540000000761,
      "styleRecalcs": 9,
      "styleRecalcDurationMs": 9.642999999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 432.848,
      "heapDeltaBytes": 23016828,
      "heapUsedBytes": 71454072,
      "domNodes": 18,
      "jsHeapTotalBytes": 14942208,
      "scriptDurationMs": 21.589000000000006,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66999999999998,
      "p95FrameDurationMs": 16.699999999999818
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1733.1949999999665,
      "styleRecalcs": 76,
      "styleRecalcDurationMs": 40.759,
      "layouts": 16,
      "layoutDurationMs": 4.800000000000001,
      "taskDurationMs": 764.358,
      "heapDeltaBytes": 14420252,
      "heapUsedBytes": 62310312,
      "domNodes": 62,
      "jsHeapTotalBytes": 15466496,
      "scriptDurationMs": 110.36,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1682.6770000000124,
      "styleRecalcs": 75,
      "styleRecalcDurationMs": 40.373,
      "layouts": 16,
      "layoutDurationMs": 4.4590000000000005,
      "taskDurationMs": 727.2769999999999,
      "heapDeltaBytes": 14402032,
      "heapUsedBytes": 62905824,
      "domNodes": 60,
      "jsHeapTotalBytes": 15204352,
      "scriptDurationMs": 104.34299999999999,
      "eventListeners": 4,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "subgraph-mouse-sweep",
      "durationMs": 1757.2129999999788,
      "styleRecalcs": 75,
      "styleRecalcDurationMs": 40.024,
      "layouts": 16,
      "layoutDurationMs": 4.504,
      "taskDurationMs": 785.0429999999999,
      "heapDeltaBytes": -1365872,
      "heapUsedBytes": 46996664,
      "domNodes": -262,
      "jsHeapTotalBytes": 15069184,
      "scriptDurationMs": 107.41300000000001,
      "eventListeners": -131,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.800000000000182
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8198.429999999973,
      "styleRecalcs": 250,
      "styleRecalcDurationMs": 54.294999999999995,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 4159.284,
      "heapDeltaBytes": 10774816,
      "heapUsedBytes": 69070188,
      "domNodes": -265,
      "jsHeapTotalBytes": 7577600,
      "scriptDurationMs": 1348.4199999999998,
      "eventListeners": -111,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8271.413999999935,
      "styleRecalcs": 250,
      "styleRecalcDurationMs": 54.44799999999999,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 4502.509,
      "heapDeltaBytes": 21133060,
      "heapUsedBytes": 78224840,
      "domNodes": -261,
      "jsHeapTotalBytes": 8626176,
      "scriptDurationMs": 1590.968,
      "eventListeners": -111,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.66333333333332,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "viewport-pan-sweep",
      "durationMs": 8177.445000000034,
      "styleRecalcs": 249,
      "styleRecalcDurationMs": 54.161,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 4191.372,
      "heapDeltaBytes": 9305792,
      "heapUsedBytes": 67545176,
      "domNodes": -263,
      "jsHeapTotalBytes": 6266880,
      "scriptDurationMs": 1380.912,
      "eventListeners": -111,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.670000000000012,
      "p95FrameDurationMs": 16.700000000000728
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 12982.458000000008,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 12967.167,
      "heapDeltaBytes": -51044948,
      "heapUsedBytes": 169640232,
      "domNodes": -9850,
      "jsHeapTotalBytes": 21295104,
      "scriptDurationMs": 634.1699999999998,
      "eventListeners": -23961,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.220000000000073,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 12628.350000000068,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 12611.270999999999,
      "heapDeltaBytes": -52509492,
      "heapUsedBytes": 173032320,
      "domNodes": -9850,
      "jsHeapTotalBytes": 25489408,
      "scriptDurationMs": 640.4069999999999,
      "eventListeners": -23954,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.223333333333237,
      "p95FrameDurationMs": 16.80000000000291
    },
    {
      "name": "vue-large-graph-idle",
      "durationMs": 13095.962999999983,
      "styleRecalcs": 0,
      "styleRecalcDurationMs": 0,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 13077.715,
      "heapDeltaBytes": -45629776,
      "heapUsedBytes": 181846288,
      "domNodes": -9848,
      "jsHeapTotalBytes": -9113600,
      "scriptDurationMs": 634.3639999999999,
      "eventListeners": -23957,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 17.219999999999953,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 15812.74400000001,
      "styleRecalcs": 81,
      "styleRecalcDurationMs": 20.272000000000013,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 15790.467,
      "heapDeltaBytes": -61336292,
      "heapUsedBytes": 165164268,
      "domNodes": -9850,
      "jsHeapTotalBytes": -8851456,
      "scriptDurationMs": 993.4690000000002,
      "eventListeners": -23983,
      "totalBlockingTimeMs": 7,
      "frameDurationMs": 17.223333333333358,
      "p95FrameDurationMs": 16.80000000000291
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 14752.6509999999,
      "styleRecalcs": 67,
      "styleRecalcDurationMs": 18.666000000000015,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 14730.542,
      "heapDeltaBytes": -41828500,
      "heapUsedBytes": 176238100,
      "domNodes": -9850,
      "jsHeapTotalBytes": -12083200,
      "scriptDurationMs": 913.0029999999999,
      "eventListeners": -23981,
      "totalBlockingTimeMs": 83,
      "frameDurationMs": 17.223333333333358,
      "p95FrameDurationMs": 16.799999999999272
    },
    {
      "name": "vue-large-graph-pan",
      "durationMs": 14887.180000000058,
      "styleRecalcs": 68,
      "styleRecalcDurationMs": 18.432000000000002,
      "layouts": 0,
      "layoutDurationMs": 0,
      "taskDurationMs": 14863.256,
      "heapDeltaBytes": -73693224,
      "heapUsedBytes": 155131616,
      "domNodes": -9850,
      "jsHeapTotalBytes": -11472896,
      "scriptDurationMs": 968.403,
      "eventListeners": -23983,
      "totalBlockingTimeMs": 100,
      "frameDurationMs": 17.776666666666642,
      "p95FrameDurationMs": 16.80000000000291
    },
    {
      "name": "workflow-execution",
      "durationMs": 473.6419999999839,
      "styleRecalcs": 18,
      "styleRecalcDurationMs": 28.951999999999998,
      "layouts": 5,
      "layoutDurationMs": 1.5770000000000002,
      "taskDurationMs": 144.651,
      "heapDeltaBytes": 5399592,
      "heapUsedBytes": 55130788,
      "domNodes": 167,
      "jsHeapTotalBytes": 524288,
      "scriptDurationMs": 31.758000000000003,
      "eventListeners": 69,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.663333333333338,
      "p95FrameDurationMs": 16.700000000000273
    },
    {
      "name": "workflow-execution",
      "durationMs": 459.1650000000982,
      "styleRecalcs": 15,
      "styleRecalcDurationMs": 22.945999999999998,
      "layouts": 5,
      "layoutDurationMs": 1.517,
      "taskDurationMs": 125.84700000000001,
      "heapDeltaBytes": 5009184,
      "heapUsedBytes": 54897504,
      "domNodes": 154,
      "jsHeapTotalBytes": 262144,
      "scriptDurationMs": 26.463,
      "eventListeners": 69,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.700000000000273
    },
    {
      "name": "workflow-execution",
      "durationMs": 466.47700000005443,
      "styleRecalcs": 21,
      "styleRecalcDurationMs": 25.264000000000003,
      "layouts": 4,
      "layoutDurationMs": 1.1090000000000002,
      "taskDurationMs": 122.446,
      "heapDeltaBytes": 5114776,
      "heapUsedBytes": 56145788,
      "domNodes": 178,
      "jsHeapTotalBytes": 524288,
      "scriptDurationMs": 20.857999999999993,
      "eventListeners": 69,
      "totalBlockingTimeMs": 0,
      "frameDurationMs": 16.666666666666668,
      "p95FrameDurationMs": 16.800000000000182
    }
  ]
}

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/i18n.test.ts`:
- Around line 2-3: After calling vi.resetModules(), re-import the i18n module to
get a fresh singleton instance (e.g. await import('./i18n')) and re-destructure
the bindings i18n, loadLocale, mergeCustomNodesI18n, and resolveSupportedLocale
so tests don't hold references to the old singleton; update every test block
that calls vi.resetModules() to perform this re-import and replace any top-level
references to the original imported symbols with the newly destructured ones.

In `@src/i18n.ts`:
- Around line 128-135: resolveSupportedLocale currently compares locale strings
with exact casing so inputs like "pt-br" or "zh-tw" miss matches; update
resolveSupportedLocale to perform case-insensitive matching: normalize the
incoming input and its base to lowercase (or otherwise canonicalize per BCP-47
case-insensitivity), then compare against supportedLocaleSet in a
case-insensitive way (either by lowercasing entries or by using a temporary map
from lowercased locale -> canonical SupportedLocale). Ensure the function still
returns the canonical SupportedLocale type (e.g., the original casing from
supportedLocaleSet) when a case-insensitive match on the full tag or the base
language is found, otherwise fall back to 'en'.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e11de931-eacb-4be9-947a-50f59b33a396

📥 Commits

Reviewing files that changed from the base of the PR and between 9d61b4d and 554ffbb.

📒 Files selected for processing (4)
  • src/i18n.test.ts
  • src/i18n.ts
  • src/platform/settings/constants/coreSettings.ts
  • src/views/GraphView.vue

Comment thread src/i18n.test.ts Outdated
Comment thread src/i18n.ts Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

❌ Patch coverage is 80.95238% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/i18n.ts 89.47% 2 Missing ⚠️
src/views/GraphView.vue 0.00% 2 Missing ⚠️
@@             Coverage Diff             @@
##             main   #11712       +/-   ##
===========================================
- Coverage   69.33%   54.55%   -14.79%     
===========================================
  Files        1483     1374      -109     
  Lines       83511    70267    -13244     
  Branches    22069    18677     -3392     
===========================================
- Hits        57904    38334    -19570     
- Misses      24663    31387     +6724     
+ Partials      944      546      -398     
Flag Coverage Δ
e2e ?
unit 54.55% <80.95%> (+3.07%) ⬆️

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

Files with missing lines Coverage Δ
src/platform/settings/constants/coreSettings.ts 11.94% <ø> (-58.47%) ⬇️
src/i18n.ts 92.85% <89.47%> (+27.93%) ⬆️
src/views/GraphView.vue 0.00% <0.00%> (-70.18%) ⬇️

... and 1015 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.

Address CodeRabbit feedback on PR #11712. BCP-47 tags are
case-insensitive, so older browsers emitting 'pt-br' or 'zh-tw'
should resolve to the shipped 'pt-BR'/'zh-TW' bundles instead of
falling through to 'en'.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/i18n.test.ts (1)

2-3: ⚠️ Potential issue | 🟠 Major

Re-import ./i18n after vi.resetModules().

The top-level bindings still point at the pre-reset singleton, so the suite can leak locale state across tests. The one local re-import at lines 149-152 only isolates that single case.

Suggested fix
 import { beforeEach, describe, expect, it, vi } from 'vitest'
-const { i18n, loadLocale, mergeCustomNodesI18n, resolveSupportedLocale } =
-  await import('./i18n')
+
+let i18n: typeof import('./i18n')['i18n']
+let loadLocale: typeof import('./i18n')['loadLocale']
+let mergeCustomNodesI18n: typeof import('./i18n')['mergeCustomNodesI18n']
+let resolveSupportedLocale: typeof import('./i18n')['resolveSupportedLocale']
 
 // Mock the JSON imports before importing i18n module
 vi.mock('./locales/en/main.json', () => ({ default: { welcome: 'Welcome' } }))
@@
 describe('i18n', () => {
   beforeEach(async () => {
     vi.resetModules()
+    ;({
+      i18n,
+      loadLocale,
+      mergeCustomNodesI18n,
+      resolveSupportedLocale
+    } = await import('./i18n'))
   })

Also applies to: 26-28

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/i18n.test.ts` around lines 2 - 3, The test file currently imports i18n,
loadLocale, mergeCustomNodesI18n, and resolveSupportedLocale at module scope
which holds the pre-reset singleton and leaks locale state; after calling
vi.resetModules() you must re-import those symbols so each test gets a fresh
instance—move or add an import statement (await import('./i18n')) immediately
after every vi.resetModules() call (including the setup around the tests that
previously re-imported only locally) and replace top-level bindings with
re-assigned locals from that post-reset import so i18n, loadLocale,
mergeCustomNodesI18n, and resolveSupportedLocale reference the fresh module
instance.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/i18n.test.ts`:
- Around line 183-199: The test should call loadLocale rather than only
resolveSupportedLocale to ensure the full loading path updates the active
locale/messages; update the third test to await loadLocale('pt-BR') and assert
it resolves to 'pt-BR' and that the module's active locale/messages state
reflect the shipped variant, then await loadLocale('pt') and assert it resolves
to 'en' (matching resolveSupportedLocale('pt') behavior). Use the existing
symbols loadLocale and resolveSupportedLocale to locate the code under test and
confirm the loaded locale and the module's exported active locale/messages are
updated after each load.

---

Duplicate comments:
In `@src/i18n.test.ts`:
- Around line 2-3: The test file currently imports i18n, loadLocale,
mergeCustomNodesI18n, and resolveSupportedLocale at module scope which holds the
pre-reset singleton and leaks locale state; after calling vi.resetModules() you
must re-import those symbols so each test gets a fresh instance—move or add an
import statement (await import('./i18n')) immediately after every
vi.resetModules() call (including the setup around the tests that previously
re-imported only locally) and replace top-level bindings with re-assigned locals
from that post-reset import so i18n, loadLocale, mergeCustomNodesI18n, and
resolveSupportedLocale reference the fresh module instance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7c220ef0-5b3b-47ac-9cce-7505668f50a6

📥 Commits

Reviewing files that changed from the base of the PR and between 554ffbb and 383a978.

📒 Files selected for processing (2)
  • src/i18n.test.ts
  • src/i18n.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/i18n.ts

Comment thread src/i18n.test.ts
The fallback test set Comfy.Locale='de' and expected an index.de.json
request. With the locale-clamping fix on this branch, unshipped tags
get resolved to 'en' before any template fetch, so that path no longer
fires. Switch to 'fa' (a shipped locale) and mock its index.fa.json to
404 — exercises the same fetcher-fallback code path. Drop the English
'All Templates' header assertion (the dialog is now translated to fa);
assert on a language-neutral testid instead.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
browser_tests/tests/templates.spec.ts (2)

134-137: Optional cleanup: encode intent in names instead of new block comments.

You can reduce comment drift by replacing these explanations with self-describing identifiers (e.g., simulatedMissingShippedLocale, fallbackContentTestId).

As per coding guidelines: "Avoid new usage of code comments; do not add or retain redundant comments."

Also applies to: 172-174

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@browser_tests/tests/templates.spec.ts` around lines 134 - 137, Replace the
explanatory block comments by introducing self-descriptive identifiers: create a
constant like simulatedMissingShippedLocale (set to 'fa') and use that constant
instead of the variable locale in the test, and similarly replace the comment
near lines 172-174 with a named test id (e.g., fallbackContentTestId) or
descriptive helper function; update usages in the test cases (references to
locale and any fallback assertions) to use these new identifiers so the intent
is encoded in names rather than comments.

141-143: Assert fallback behavior via response statuses (not only request URLs).

This currently proves both URLs were requested, but not that locale failed and English fallback succeeded. Switching to response-level checks makes the regression guard tighter.

Proposed tightening
-    const localeRequestPromise = comfyPage.page.waitForRequest(
-      `**/templates/index.${locale}.json`
-    )
-    const englishRequestPromise = comfyPage.page.waitForRequest(
-      '**/templates/index.json'
-    )
+    const localeResponsePromise = comfyPage.page.waitForResponse(
+      (response) =>
+        response.url().includes(`templates/index.${locale}.json`) &&
+        response.status() === 404
+    )
+    const englishResponsePromise = comfyPage.page.waitForResponse(
+      (response) =>
+        response.url().includes('templates/index.json') &&
+        response.status() === 200
+    )
@@
-    const localeRequest = await localeRequestPromise
-    const englishRequest = await englishRequestPromise
+    const localeResponse = await localeResponsePromise
+    const englishResponse = await englishResponsePromise
 
-    expect(localeRequest.url()).toContain(`templates/index.${locale}.json`)
-    expect(englishRequest.url()).toContain('templates/index.json')
+    expect(localeResponse.url()).toContain(`templates/index.${locale}.json`)
+    expect(englishResponse.url()).toContain('templates/index.json')

Also applies to: 166-170

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@browser_tests/tests/templates.spec.ts` around lines 141 - 143, The test
currently waits for requests via comfyPage.page.waitForRequest using the
localeRequestPromise variables; change these to wait for responses (use
comfyPage.page.waitForResponse) so you can assert response.status() as well as
the URL — assert that the locale response returns a failure status (e.g., !==
200 or specific 404) and that the English fallback response returns 200 to prove
fallback succeeded; apply the same change to the second occurrence around the
block currently at lines 166-170 so both locale and fallback checks validate
response statuses and URLs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@browser_tests/tests/templates.spec.ts`:
- Around line 134-137: Replace the explanatory block comments by introducing
self-descriptive identifiers: create a constant like
simulatedMissingShippedLocale (set to 'fa') and use that constant instead of the
variable locale in the test, and similarly replace the comment near lines
172-174 with a named test id (e.g., fallbackContentTestId) or descriptive helper
function; update usages in the test cases (references to locale and any fallback
assertions) to use these new identifiers so the intent is encoded in names
rather than comments.
- Around line 141-143: The test currently waits for requests via
comfyPage.page.waitForRequest using the localeRequestPromise variables; change
these to wait for responses (use comfyPage.page.waitForResponse) so you can
assert response.status() as well as the URL — assert that the locale response
returns a failure status (e.g., !== 200 or specific 404) and that the English
fallback response returns 200 to prove fallback succeeded; apply the same change
to the second occurrence around the block currently at lines 166-170 so both
locale and fallback checks validate response statuses and URLs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: eb104685-9dcb-41eb-af46-2126cece81a7

📥 Commits

Reviewing files that changed from the base of the PR and between 383a978 and 68fa1a4.

📒 Files selected for processing (1)
  • browser_tests/tests/templates.spec.ts

@dante01yoon dante01yoon added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch core/1.43 Backport PRs for core 1.43 cloud/1.43 Backport PRs for cloud 1.43 labels Apr 28, 2026
Comment thread src/i18n.ts Outdated
'zh',
'zh-TW',
'pt-BR'
] as const
Copy link
Copy Markdown
Collaborator

@jtydhr88 jtydhr88 Apr 30, 2026

Choose a reason for hiding this comment

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

Avoid adding a 5th hand-rolled locale list, consolidate to one source of truth instead.

This file already maintains the same set of locales in four separate places: localeLoaders, nodeDefsLoaders, commandsLoaders, and settingsLoaders. Adding SUPPORTED_LOCALES makes it five (and Comfy.Locale.options in coreSettings.ts is a sixth). Each new language now requires touching six locations, and any one of them being out of sync produces a silent bug — e.g. a locale present in the dropdown but missing a loader, or shipped messages that resolveSupportedLocale refuses to recognize.

We should treat this as a chance to unify rather than to duplicate.

Copy link
Copy Markdown
Collaborator Author

@dante01yoon dante01yoon Apr 30, 2026

Choose a reason for hiding this comment

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

Thanks, agreed. I consolidated the locale source of truth here.

The main fix landed in d6f1b9c: src/locales/localeConfig.ts now owns the supported locale keys, display labels, and lazy loaders. coreSettings.ts derives the dropdown options from SUPPORTED_LOCALE_OPTIONS, and i18n.ts resolves/loads locales from the same localeDefinitions map, so adding a locale no longer requires keeping the previous loader maps and settings options in sync manually.

I also pushed e70382649 to update the locale contributor troubleshooting note to point at the new shared config file.

@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 Apr 30, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/locales/CONTRIBUTING.md (1)

143-146: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Troubleshooting step still points to outdated config file.

After centralizing locale wiring in src/locales/localeConfig.ts, the “Language not appearing in dropdown” guidance at Line 145 still tells contributors to check coreSettings.ts. Please update this reference to src/locales/localeConfig.ts to avoid misconfiguration during new locale additions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/locales/CONTRIBUTING.md` around lines 143 - 146, Update the
troubleshooting text that points contributors to the wrong config file: replace
the reference to coreSettings.ts with the centralized locale wiring file
src/locales/localeConfig.ts in the CONTRIBUTING.md “Language not appearing in
dropdown” section so new locale additions check the correct file (ensure the
exact filename and path src/locales/localeConfig.ts are used in that guidance).
🧹 Nitpick comments (1)
src/i18n.test.ts (1)

187-227: ⚡ Quick win

Good unit coverage—please add/land the E2E regression in browser_tests/ (or document why not feasible).

Given this is a bug-fix PR, please ensure the regression spec is committed under browser_tests/ (not only temp/scripts/...) or add a concrete PR note explaining why E2E is not practical here.

Based on learnings, bug-fix PRs should include browser_tests/ changes or a concrete non-placeholder explanation of why an end-to-end regression test is not practical.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/i18n.test.ts` around lines 187 - 227, The PR is missing an E2E regression
under browser_tests for the i18n loadLocale behaviors exercised in
src/i18n.test.ts; add a browser_tests spec that reproduces the key scenarios
(reloading same locale, unsupported locale clamped to "en", preservation of
shipped BCP-47 tags like "zh-TW" and "pt-BR", and concurrent loadLocale('zh')
calls) or, if an E2E test truly cannot be implemented, add a concrete PR note
under browser_tests/ explaining why (environmental constraints, flakiness, or
test infra gaps) and link to the unit tests (loadLocale) verifying the fix;
ensure the test file references loadLocale and asserts resolved locale values
and message availability for "pt-BR" as in the unit tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/locales/CONTRIBUTING.md`:
- Around line 143-146: Update the troubleshooting text that points contributors
to the wrong config file: replace the reference to coreSettings.ts with the
centralized locale wiring file src/locales/localeConfig.ts in the
CONTRIBUTING.md “Language not appearing in dropdown” section so new locale
additions check the correct file (ensure the exact filename and path
src/locales/localeConfig.ts are used in that guidance).

---

Nitpick comments:
In `@src/i18n.test.ts`:
- Around line 187-227: The PR is missing an E2E regression under browser_tests
for the i18n loadLocale behaviors exercised in src/i18n.test.ts; add a
browser_tests spec that reproduces the key scenarios (reloading same locale,
unsupported locale clamped to "en", preservation of shipped BCP-47 tags like
"zh-TW" and "pt-BR", and concurrent loadLocale('zh') calls) or, if an E2E test
truly cannot be implemented, add a concrete PR note under browser_tests/
explaining why (environmental constraints, flakiness, or test infra gaps) and
link to the unit tests (loadLocale) verifying the fix; ensure the test file
references loadLocale and asserts resolved locale values and message
availability for "pt-BR" as in the unit tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4a0822a6-d229-4f32-b881-d5bd7627b043

📥 Commits

Reviewing files that changed from the base of the PR and between 68fa1a4 and d6f1b9c.

📒 Files selected for processing (5)
  • src/i18n.test.ts
  • src/i18n.ts
  • src/locales/CONTRIBUTING.md
  • src/locales/localeConfig.ts
  • src/platform/settings/constants/coreSettings.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/platform/settings/constants/coreSettings.ts

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 30, 2026
@dante01yoon dante01yoon removed their assignment Apr 30, 2026
@dante01yoon
Copy link
Copy Markdown
Collaborator Author

dante01yoon commented Apr 30, 2026

Follow-up on the latest review notes:

  • Updated the outdated src/locales/CONTRIBUTING.md troubleshooting reference to point at src/locales/localeConfig.ts in e70382649.
  • On the E2E note: this PR already includes the browser regression in browser_tests/tests/templates.spec.ts for the user-visible locale template fallback path with a shipped locale returning 404 and English fallback loading. The extra loadLocale cases called out here are module-level behavior (canonical resolver output, singleton loading state, pt-BR message availability, and duplicate-load dedupe), so I kept them in src/i18n.test.ts rather than adding a Playwright test that would need to reach into app internals.

Copy link
Copy Markdown
Collaborator

@jtydhr88 jtydhr88 left a comment

Choose a reason for hiding this comment

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

Code looks good to me, also did some local testing, works fine. Since this refactors core i18n behavior, I'd like to bring in a second reviewer.

One thing worth verifying before merge: please confirm this doesn't break the custom node i18n flow. Could you load one or two custom nodes that ship locale bundles and confirm their translated strings still render correctly?

Want to make sure the mergeCustomNodesI18n path still works with the new resolution flow

@jtydhr88 jtydhr88 assigned DrJKL and unassigned jtydhr88 May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cloud/1.43 Backport PRs for cloud 1.43 core/1.43 Backport PRs for core 1.43 needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sidebar button labels broken

5 participants