Reuse Dygraph line chart data structures#223
Merged
Merged
Conversation
ktsaou
marked this pull request as ready for review
July 16, 2026 12:48
novykh
approved these changes
Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Root cause
Dygraphs' default line handler reconstructs extracted
[x, y]pairs and point records on every data update. A chart with thousands of dimensions therefore creates millions of short-lived arrays and objects per refresh, increasing preparation time, heap growth, and garbage-collection pressure even when the response shape is unchanged.Measured benefit
An isolated local preparation benchmark used the production CommonJS build on Node.js 22.22.2 with 6,000 dimensions × 297 timestamps (1,782,000 values). Both handlers were warmed first, all values changed before every sample, 20 samples per handler were run in alternating order, and explicit garbage collection preceded each sample.
The measured scope is exactly the stage changed by this PR:
extractSeriesplusseriesToPoints.The heap figures measure additional allocation during one update, not total retained chart heap. The reusable-handler baseline already contains the current chart structures.
The first render still constructs the arrays and point objects. These results apply to subsequent structurally compatible updates. They exclude response creation, SDK transformation, extrema and range calculation, layout, and canvas drawing; no end-to-end rendering percentage is claimed.
What is reused — and what is not
This change reuses allocations, not data.
Every new response is still fully processed:
[x, y]pair receives the latest timestamp and value, including corrected historical valuesxvalandyvalThe handler does not cache query results, skip values, or keep previous values merely because the response shape is unchanged.
A response is structurally compatible only when:
If dimensions connect, disconnect, reconnect, or replicate and this changes the label sequence or row count, the reusable containers are discarded and rebuilt. If the structure stays the same but any current or historical values change, the containers are retained and every value is overwritten from the new response.
Behavior and compatibility
This uses Dygraphs' supported public
dataHandlerextension point; it does not fork Dygraphs or mutate undocumented Dygraphs state.Queries, payloads, chart results, line rendering, gaps, logarithmic scales, rolling windows, annotations, zoom behavior, and stacked-chart behavior remain unchanged. Structural incompatibility causes a safe rebuild; duplicate labels use Dygraphs' original handler.
Validation