Skip to content

fix: compare Taro chart specs safely - #4723

Open
dajiaohuang wants to merge 2 commits into
VisActor:developfrom
dajiaohuang:fix/4656-taro-spec-comparison-qitem-20261022
Open

dajiaohuang wants to merge 2 commits into
VisActor:developfrom
dajiaohuang:fix/4656-taro-spec-comparison-qitem-20261022

Conversation

@dajiaohuang

Copy link
Copy Markdown
Contributor

🤔 This is a ...

  • Bug fix
  • Test Case

🔗 Related issue link

Fixes #4656

💡 Background and solution

Both Taro wrappers used JSON.stringify as the spec-change guard. The shared comparator now compares functions by reference, handles cyclic arrays/plain objects, and compares Date values by timestamp. It retains structural comparison, so a newly allocated but equivalent spec still skips updateSpec instead of switching to a reference-only guard.

A synthetic cost check on Node v24.14.1 compared two equal specs containing 10,000 data rows (3 samples × 100 comparisons after warmup): JSON serialization took 89.3–92.3 ms per 100 comparisons; the cycle-safe comparator took 114.1–120.0 ms per 100 (~0.23–0.31 ms additional per comparison). This measures the comparison only, not full chart rendering.

📝 Changelog

Language Changelog
🇺🇸 English Apply callback-only and cyclic spec updates in Taro VChart without JSON serialization.
🇨🇳 Chinese Taro VChart 配置比较支持函数回调和循环引用,避免 JSON 序列化异常。

☑️ Self-Check before Merge

  • Doc update is not needed for this implementation fix
  • Demo is not needed
  • TypeScript definitions are unchanged
  • Changelog is provided

Validation: npm test in packages/taro-vchart passed (callback identity, structurally equal specs, Dates, and equal/different cycles). The helper passed strict TypeScript 4.9.5 checking. Full package build was not run because workspace dependencies are not installed in this task checkout.

@visactor-review-bot visactor-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Found 2 issues that need fixing; see the inline comments.


const leftIsArray = Array.isArray(left);
if (leftIsArray !== Array.isArray(right)) return false;
if (!leftIsArray && (!isPlainObject(left) || !isPlainObject(right))) return false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P2] Avoid treating recreated class-valued data rows as changed specs

With freshly constructed data rows having the same enumerable fields (e.g. new Row('A', 3) on each render), this line returns false at the first row. VChart's datum shape accepts arbitrary fields, and both wrappers interpret false as a reason to call updateSpec(..., true). A Node 22 reproduction using this comparator returned unequal on 100/100 equivalent rerenders, whereas the former JSON guard returned equal. Large datasets or dashboards consequently merge/render unchanged charts repeatedly. Compare enumerable fields of supported row objects, or handle this case at the wrapper boundary. This reproduces the comparator/guard, not a full Taro integration test.

const leftObject = left as object;
const rightObject = right as object;
const activeRight = active.get(leftObject);
if (activeRight) return activeRight === rightObject;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P2] Distinguish cyclic data graphs that share a right-hand node

active only tracks left-to-right pairs, so two different active left nodes may map to the same right node. For data values containing a two-node cycle versus a one-node self-cycle with identical scalar fields, isSpecEqual(oldSpec, newSpec) returns true while the reverse comparison returns false (reproduced using the actual comparator under Node 22). Since the wrappers call updateSpec only when this returns false, replacing such cyclic data is silently ignored. Track the reverse active mapping too, so changed cycle topology cannot compare equal. Full chart integration was not runnable without workspace dependencies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] taro-vchart misses function-only spec updates and throws on cyclic specs

1 participant