Skip to content

feat: add observerMap deepMerge no-op performance benchmarks to fast-html #7580

Description

@janechu

🙋 Feature Request

Add targeted performance coverage for observerMap-managed deepMerge no-op array payloads before introducing any new array equality fast path.

This is a follow-up investigation for #7559.

🤔 Expected Behavior

deepMerge should preserve the current behavior where structurally equal arrays are treated as no-ops, while giving maintainers visibility into the cost of proving that no-op for large or frequently synced arrays.

If a fast path is added, it should only optimize cases that are cheaper to prove unchanged, such as:

  • Object.is(targetValue, sourceValue)
  • both values are arrays with the same length and the same element identity at every index

It should not replace the existing deep-equality semantics with shallow equality.

😯 Current Behavior

deepMerge already calls deepEqual(targetValue, sourceValue) before entering the array replacement branch. Deep-equal arrays are therefore already skipped without allocating a replacement array, cloning items, or notifying observers.

The remaining performance risk is the cost of the deep comparison itself for large or frequently synced arrays. Consumers doing high-frequency syncs, polling, streaming updates, or redux-style hydration can still pay an O(n) or deep tree-walk cost on no-op payloads.

💁 Possible Solution

Measure before changing behavior. Add a benchmark or micro-benchmark, if appropriate for fast-html, that exercises observerMap-managed deepMerge against arrays and nested object arrays at varying sizes/depths.

Suggested acceptance coverage:

  • A test documenting the current contract: structurally equal arrays do not cause replacement or notification.
  • If a fast path is added, a targeted test verifies that same-reference or same-element arrays skip the expensive path without changing observable behavior.
  • Benchmark numbers showing no regression for the replacement case and a clear win for any measured no-op case.

🔦 Context

PR #7559 changed non-equal observerMap arrays to be replaced rather than spliced in place. During follow-up review, array identity and repeated sync performance came up as risk areas. The equality no-op behavior is already preserved today, so this issue is about measuring and optimizing carefully rather than changing semantics speculatively.

Searched existing issues for overlapping observerMap/deepMerge performance reports and did not find a duplicate.

💻 Examples

const data = {
    items: [{ id: 1, label: "A", metrics: { views: 1 } }],
};

// This should remain a no-op by structural equality.
deepMerge(data, {
    items: [{ id: 1, label: "A", metrics: { views: 1 } }],
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    improvementA non-feature-adding improvementstatus:triageNew Issue - needs triage

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions