Skip to content

perf: reduce chart mounting and serialization work - #140

Merged
tannerlinsley merged 5 commits into
mainfrom
taren/release-charts-performance
Sep 8, 2026
Merged

perf: reduce chart mounting and serialization work#140
tannerlinsley merged 5 commits into
mainfrom
taren/release-charts-performance

Conversation

@tannerlinsley

@tannerlinsley tannerlinsley commented Sep 8, 2026

Copy link
Copy Markdown
Member

Dense React charts built and serialized twice on client mount, and SVG mounts created a hidden focus circle for every data point. This removes the duplicate client work, creates default focus circles only when needed, and reduces SVG serialization and categorical domain allocation costs. Server rendering, hydration, authored focus layers, and animated updates retain their existing behavior.

Includes a patch changeset for the fixed package group, refreshed bundle and catalog preview evidence, and a package-check fix that gives its isolated consumer the repository's pinned package manager.

Validation:

  • Full workspace validation.
  • 973 core and React tests, including Strict Mode hydration, custom SVG rendering, focus, animation, and typography updates.
  • Seven native Chromium before/after screenshots are byte-identical across SVG, canvas, axes, pointer focus, and keyboard focus.
  • All 188 catalog previews regenerate, with changes limited to inactive default focus circles in eight previews.
  • Representative React line consumer: +365 gzip bytes. Dependency isolation passes and competitor bundles are unchanged.

Measured against 0.16.1 (7117aca3), production React, Chromium, Apple M5 Pro, 500×300 heatmap with 10,000 cells, 10 warmups and 30 measured mounts per version, alternating order:

Time from mount to paint, median Before After
SVG, with axes 164.3 ms 37.9 ms
Canvas, with axes 42.8 ms 25.8 ms
SVG, without axes 133.4 ms 35.9 ms
Canvas, without axes 38.8 ms 23.6 ms

Both versions use identical features and data, without animation. These are local chart measurements, not network loading or extrapolated dashboard totals.

Summary by CodeRabbit

  • New Features

    • Improved chart mounting and server-rendered hydration for React charts, including Strict Mode compatibility.
    • Added smoother focus and interaction rendering during animated updates.
    • Improved SVG output for focus guides, clipping, labels, and special characters.
  • Bug Fixes

    • Categorical scales now correctly deduplicate valid dates and values while ignoring invalid entries.
    • Reduced unnecessary font measurements and duplicate chart builds during mounting.
    • Improved cleanup after rendering errors and deferred focus updates.

@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 2bd08a7f-456f-4871-98fb-0d09334566cc

📥 Commits

Reviewing files that changed from the base of the PR and between a100372 and 67fe19b.

⛔ Files ignored due to path filters (8)
  • benchmarks/conformance/previews/34-pointer-tooltip.svg is excluded by !**/*.svg
  • benchmarks/conformance/previews/35-grouped-tooltip.svg is excluded by !**/*.svg
  • benchmarks/conformance/previews/65-voronoi-nearest-tooltip.svg is excluded by !**/*.svg
  • benchmarks/conformance/previews/81-recharts-interactive-legend.svg is excluded by !**/*.svg
  • benchmarks/conformance/previews/82-chart-table-selection.svg is excluded by !**/*.svg
  • benchmarks/conformance/previews/83-focus-context-window.svg is excluded by !**/*.svg
  • benchmarks/conformance/previews/84-pinned-nested-chart-tooltip.svg is excluded by !**/*.svg
  • benchmarks/conformance/previews/86-streaming-window-preservation.svg is excluded by !**/*.svg
📒 Files selected for processing (26)
  • .changeset/quick-charts-mount.md
  • API-FRICTION.md
  • benchmarks/bundle-size/universal-baseline.json
  • benchmarks/comparison/bundle-baseline.json
  • benchmarks/conformance/previews/manifest.json
  • docs/comparison.md
  • packages/charts-core/docs/comparison.md
  • packages/charts-core/src/canvas.ts
  • packages/charts-core/src/configured-scale.test.ts
  • packages/charts-core/src/default-focus-internal.ts
  • packages/charts-core/src/focus-layer.ts
  • packages/charts-core/src/markup-internal.ts
  • packages/charts-core/src/scale-input.ts
  • packages/charts-core/src/scene.ts
  • packages/charts-core/src/svg-focus-guide-serializer.ts
  • packages/charts-core/src/svg-render-context-internal.ts
  • packages/charts-core/src/svg-renderer.test.ts
  • packages/charts-core/src/svg-renderer.ts
  • packages/charts-core/src/svg-surface.test.ts
  • packages/charts-core/src/svg-surface.ts
  • packages/charts-core/src/svg.ts
  • packages/react-charts/src/CanvasChart.test.tsx
  • packages/react-charts/src/Chart.test.tsx
  • packages/react-charts/src/RendererChart.tsx
  • scripts/measure-bundles.mjs
  • scripts/unified-package-artifact.mjs

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

The change updates SVG focus serialization, categorical scale inference, React chart mounting and hydration, escaping utilities, regression coverage, and related benchmark and release metadata.

Changes

Chart rendering and mounting

Layer / File(s) Summary
Shared SVG serialization pipeline
packages/charts-core/src/markup-internal.ts, packages/charts-core/src/svg-renderer.ts, packages/charts-core/src/svg-focus-guide-serializer.ts, packages/charts-core/src/svg.ts, packages/charts-core/src/canvas.ts
Shared escaping, numeric formatting, clipping, child-rendering context, and focus-layer serialization are used across SVG and canvas prerender paths.
Default-focus rendering lifecycle
packages/charts-core/src/default-focus-internal.ts, packages/charts-core/src/scene.ts, packages/charts-core/src/svg-surface.ts, packages/charts-core/src/focus-layer.ts, packages/charts-core/src/svg-surface.test.ts
Default-focus layers are marked, filtered, eagerly prepared for animation, and reconciled without serializing inactive geometry.
Categorical domain inference
packages/charts-core/src/scale-input.ts, packages/charts-core/src/configured-scale.test.ts
Categorical inference preserves valid value types, deduplicates dates by timestamp, and ignores invalid values.
React mount and hydration lifecycle
packages/react-charts/src/RendererChart.tsx, packages/react-charts/src/Chart.test.tsx, packages/react-charts/src/CanvasChart.test.tsx
Initial prerendering, hydration snapshots, adapter mounting, cleanup, and later updates are separated. Tests cover single-build behavior, font refresh, canvas mounting, and SVG reuse during hydration.
Validation records and release metadata
.changeset/quick-charts-mount.md, API-FRICTION.md, benchmarks/*, docs/comparison.md, packages/charts-core/docs/comparison.md, scripts/measure-bundles.mjs, scripts/unified-package-artifact.mjs
Release notes, performance records, bundle budgets, benchmark data, preview manifests, comparison snapshots, and packed-consumer package-manager handling are updated.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 67fe1

The rendering and mounting optimizations retain the covered server, hydration, focus, animation, and scale behaviors, with no actionable merge risk identified.

Sequence Diagram(s)

sequenceDiagram
  participant ReactDOM
  participant RendererChart
  participant SVGSurface
  ReactDOM->>RendererChart: render server snapshot
  RendererChart->>SVGSurface: prerender initial markup
  ReactDOM->>RendererChart: hydrate client tree
  RendererChart->>SVGSurface: mount and apply layout update
  SVGSurface-->>ReactDOM: reuse existing SVG nodes
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.78% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 36 functions across 19 files. (7 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the PR's primary performance improvements to chart mounting and serialization.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 2.78% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 36 functions across 19 files. (7 skipped: 7 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch taren/release-charts-performance

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

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

@nx-cloud

nx-cloud Bot commented Sep 8, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 67fe19b

Command Status Duration Result
nx run charts-workspace:ci-distributed ✅ Succeeded 6m 5s View ↗
nx run charts-workspace:package-check ✅ Succeeded 2m 18s View ↗
nx run charts-workspace:benchmark-check ✅ Succeeded 1m 7s View ↗

☁️ Nx Cloud last updated this comment at 2026-09-08 23:06:47 UTC

@tannerlinsley
tannerlinsley merged commit b62087f into main Sep 8, 2026
18 checks passed
@github-actions github-actions Bot mentioned this pull request Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant