Skip to content

Performance: compat shallowDiffers#4780

Merged
rschristian merged 2 commits into
preactjs:mainfrom
romgrk:perf-shallow-compare
May 27, 2026
Merged

Performance: compat shallowDiffers#4780
rschristian merged 2 commits into
preactjs:mainfrom
romgrk:perf-shallow-compare

Conversation

@romgrk
Copy link
Copy Markdown
Contributor

@romgrk romgrk commented May 29, 2025

This util is used to compare props. Props are more likely (I'm guessing) to have the same shape from one render to the next. Therefore, it's better to check first if the values differ than if the keys differ.

This benchmark compares 20-keys objects with the same shape for the same-values and different-values cases.

image

Benchmark: https://github.com/romgrk/js-benchmark/blob/master/benchmarks/object-shallow-compare.js

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 29, 2025

📊 Tachometer Benchmark Results

Summary

duration

  • create10k: unsure 🔍 -1% - +0% (-5.93ms - +4.00ms)
    preact-local vs preact-main
  • filter-list: unsure 🔍 -0% - +0% (-0.02ms - +0.05ms)
    preact-local vs preact-main
  • hydrate1k: unsure 🔍 -2% - +1% (-1.60ms - +0.96ms)
    preact-local vs preact-main
  • many-updates: unsure 🔍 -4% - +3% (-0.60ms - +0.51ms)
    preact-local vs preact-main
  • replace1k: unsure 🔍 -1% - +3% (-0.53ms - +1.73ms)
    preact-local vs preact-main
  • text-update: unsure 🔍 -5% - +4% (-0.09ms - +0.07ms)
    preact-local vs preact-main
  • todo: faster ✔ 0% - 2% (0.04ms - 0.72ms)
    preact-local vs preact-main
  • update10th1k: unsure 🔍 -4% - +3% (-1.42ms - +1.13ms)
    preact-local vs preact-main

usedJSHeapSize

  • create10k: unsure 🔍 -0% - +0% (-0.00ms - +0.00ms)
    preact-local vs preact-main
  • filter-list: unsure 🔍 -0% - +0% (-0.01ms - +0.00ms)
    preact-local vs preact-main
  • hydrate1k: unsure 🔍 -2% - +2% (-0.10ms - +0.10ms)
    preact-local vs preact-main
  • many-updates: unsure 🔍 -0% - +0% (-0.00ms - +0.00ms)
    preact-local vs preact-main
  • replace1k: unsure 🔍 -0% - +0% (-0.00ms - +0.00ms)
    preact-local vs preact-main
  • text-update: unsure 🔍 -2% - +5% (-0.02ms - +0.05ms)
    preact-local vs preact-main
  • todo: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-main
  • update10th1k: unsure 🔍 -0% - +0% (-0.01ms - +0.01ms)
    preact-local vs preact-main

Results

create10k

duration

VersionAvg timevs preact-localvs preact-main
preact-local879.58ms - 886.89ms-unsure 🔍
-1% - +0%
-5.93ms - +4.00ms
preact-main880.85ms - 887.55msunsure 🔍
-0% - +1%
-4.00ms - +5.93ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local19.05ms - 19.05ms-unsure 🔍
-0% - +0%
-0.00ms - +0.00ms
preact-main19.05ms - 19.05msunsure 🔍
-0% - +0%
-0.00ms - +0.00ms
-
filter-list

duration

VersionAvg timevs preact-localvs preact-main
preact-local16.55ms - 16.59ms-unsure 🔍
-0% - +0%
-0.02ms - +0.05ms
preact-main16.53ms - 16.58msunsure 🔍
-0% - +0%
-0.05ms - +0.02ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local1.55ms - 1.56ms-unsure 🔍
-0% - +0%
-0.01ms - +0.00ms
preact-main1.55ms - 1.56msunsure 🔍
-0% - +0%
-0.00ms - +0.01ms
-
hydrate1k

duration

VersionAvg timevs preact-localvs preact-main
preact-local64.38ms - 66.20ms-unsure 🔍
-2% - +1%
-1.60ms - +0.96ms
preact-main64.71ms - 66.51msunsure 🔍
-1% - +2%
-0.96ms - +1.60ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local5.08ms - 5.22ms-unsure 🔍
-2% - +2%
-0.10ms - +0.10ms
preact-main5.08ms - 5.22msunsure 🔍
-2% - +2%
-0.10ms - +0.10ms
-
many-updates

duration

VersionAvg timevs preact-localvs preact-main
preact-local16.20ms - 17.04ms-unsure 🔍
-4% - +3%
-0.60ms - +0.51ms
preact-main16.31ms - 17.02msunsure 🔍
-3% - +4%
-0.51ms - +0.60ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local3.73ms - 3.74ms-unsure 🔍
-0% - +0%
-0.00ms - +0.00ms
preact-main3.73ms - 3.74msunsure 🔍
-0% - +0%
-0.00ms - +0.00ms
-
replace1k
  • Browser: chrome-headless
  • Sample size: 100
  • Built by: CI #5529
  • Commit: 6ff68b7

duration

VersionAvg timevs preact-localvs preact-main
preact-local60.54ms - 62.07ms-unsure 🔍
-1% - +3%
-0.53ms - +1.73ms
preact-main59.88ms - 61.53msunsure 🔍
-3% - +1%
-1.73ms - +0.53ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local3.00ms - 3.00ms-unsure 🔍
-0% - +0%
-0.00ms - +0.00ms
preact-main3.00ms - 3.00msunsure 🔍
-0% - +0%
-0.00ms - +0.00ms
-

run-warmup-0

VersionAvg timevs preact-localvs preact-main
preact-local28.06ms - 28.83ms-unsure 🔍
-3% - +1%
-0.84ms - +0.30ms
preact-main28.29ms - 29.14msunsure 🔍
-1% - +3%
-0.30ms - +0.84ms
-

run-warmup-1

VersionAvg timevs preact-localvs preact-main
preact-local33.79ms - 34.78ms-unsure 🔍
-1% - +3%
-0.45ms - +0.96ms
preact-main33.53ms - 34.53msunsure 🔍
-3% - +1%
-0.96ms - +0.45ms
-

run-warmup-2

VersionAvg timevs preact-localvs preact-main
preact-local34.36ms - 35.41ms-unsure 🔍
-3% - +1%
-1.18ms - +0.30ms
preact-main34.80ms - 35.86msunsure 🔍
-1% - +3%
-0.30ms - +1.18ms
-

run-warmup-3

VersionAvg timevs preact-localvs preact-main
preact-local27.38ms - 27.89ms-unsure 🔍
-1% - +2%
-0.27ms - +0.50ms
preact-main27.23ms - 27.81msunsure 🔍
-2% - +1%
-0.50ms - +0.27ms
-

run-warmup-4

VersionAvg timevs preact-localvs preact-main
preact-local24.65ms - 26.23ms-unsure 🔍
-3% - +6%
-0.66ms - +1.54ms
preact-main24.23ms - 25.76msunsure 🔍
-6% - +3%
-1.54ms - +0.66ms
-

run-final

VersionAvg timevs preact-localvs preact-main
preact-local22.05ms - 22.66ms-unsure 🔍
-1% - +3%
-0.26ms - +0.74ms
preact-main21.72ms - 22.51msunsure 🔍
-3% - +1%
-0.74ms - +0.26ms
-
text-update

duration

VersionAvg timevs preact-localvs preact-main
preact-local1.79ms - 1.90ms-unsure 🔍
-5% - +4%
-0.09ms - +0.07ms
preact-main1.79ms - 1.91msunsure 🔍
-4% - +5%
-0.07ms - +0.09ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local0.99ms - 1.05ms-unsure 🔍
-2% - +5%
-0.02ms - +0.05ms
preact-main0.99ms - 1.03msunsure 🔍
-5% - +2%
-0.05ms - +0.02ms
-
todo

duration

VersionAvg timevs preact-localvs preact-main
preact-local30.65ms - 30.91ms-faster ✔
0% - 2%
0.04ms - 0.72ms
preact-main30.84ms - 31.48msslower ❌
0% - 2%
0.04ms - 0.72ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local1.26ms - 1.26ms-unsure 🔍
+0% - +0%
+0.00ms - +0.00ms
preact-main1.26ms - 1.26msunsure 🔍
-0% - -0%
-0.00ms - -0.00ms
-
update10th1k

duration

VersionAvg timevs preact-localvs preact-main
preact-local34.70ms - 36.36ms-unsure 🔍
-4% - +3%
-1.42ms - +1.13ms
preact-main34.70ms - 36.64msunsure 🔍
-3% - +4%
-1.13ms - +1.42ms
-

usedJSHeapSize

VersionAvg timevs preact-localvs preact-main
preact-local2.96ms - 2.98ms-unsure 🔍
-0% - +0%
-0.01ms - +0.01ms
preact-main2.96ms - 2.98msunsure 🔍
-0% - +0%
-0.01ms - +0.01ms
-

tachometer-reporter-action v2 for CI

@romgrk
Copy link
Copy Markdown
Contributor Author

romgrk commented May 23, 2026

Ping, and you can close the PR if it's not going to be merged.

@rschristian
Copy link
Copy Markdown
Member

Thanks for the ping, sorry this PR slipped our notice.

I believe this is only used for memo() & PureComponent, both of which are pretty uncommon nowadays. Did you run into any detectable issue with one of them to end up looking at this? Just curious; I think it's a fine change & I agree changing values will occur more often.

Just needs a rebase, and also, main is targeting the upcoming v11, v10.x is the branch for the v10 release line. You can mirror this to v10 if you want or not

@romgrk
Copy link
Copy Markdown
Contributor Author

romgrk commented May 27, 2026

I didn't notice any issue, I was just reading the codebase to understand the differences with React and noticed it. It's more of a lint. I'm happy with just targetting main.

@coveralls
Copy link
Copy Markdown

Coverage Status

coverage: 98.528%. remained the same — romgrk:perf-shallow-compare into preactjs:main

@rschristian rschristian merged commit 7d8929f into preactjs:main May 27, 2026
13 checks passed
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.

3 participants