nolanlawson / emoji-picker-element

A lightweight emoji picker for the modern web
https://nolanlawson.github.io/emoji-picker-element/
Apache License 2.0
1.49k stars 85 forks source link

perf: avoid unnecessary re-renders #437

Closed nolanlawson closed 2 months ago

nolanlawson commented 2 months ago

This is an experiment where we avoid additional re-renders by 1) not forcing an update to the state is object equality is still the same, and 2) avoiding an extra re-render if the browser supports all ZWJ-containing emoji.

Probably needs a battery of tests before it can be merged, but opening the PR anyway.

github-actions[bot] commented 2 months ago

📊 Tachometer Benchmark Results

Summary

benchmark-total

  • emoji-picker-element-change-tab: unsure 🔍 -8% - +1% (-2.90ms - +0.26ms)
    this-change vs tip-of-tree
  • emoji-picker-element-database-interactions: unsure 🔍 -5% - +3% (-5.08ms - +3.08ms)
    this-change vs tip-of-tree
  • emoji-picker-element-first-load: unsure 🔍 -6% - +3% (-3.38ms - +1.81ms)
    this-change vs tip-of-tree
  • emoji-picker-element-second-load: unsure 🔍 -4% - +3% (-1.85ms - +1.23ms)
    this-change vs tip-of-tree

Results

emoji-picker-element-change-tab
  • Browser: chrome-headless 127.0.6533.99
  • Sample size: 50
  • Built by: Benchmarks #464
  • Commit: fc58af5
VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
this-change
33.09ms - 34.84ms-unsure 🔍
-8% - +1%
-2.90ms - +0.26ms
tip-of-tree
tip-of-tree
33.98ms - 36.60msunsure 🔍
-1% - +9%
-0.26ms - +2.90ms
-
emoji-picker-element-database-interactions
  • Browser: chrome-headless 127.0.6533.99
  • Sample size: 50
  • Built by: Benchmarks #464
  • Commit: fc58af5
VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
this-change
100.31ms - 105.95ms-unsure 🔍
-5% - +3%
-5.08ms - +3.08ms
tip-of-tree
tip-of-tree
101.18ms - 107.08msunsure 🔍
-3% - +5%
-3.08ms - +5.08ms
-
emoji-picker-element-first-load
  • Browser: chrome-headless 127.0.6533.99
  • Sample size: 50
  • Built by: Benchmarks #464
  • Commit: fc58af5
VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
this-change
49.85ms - 53.17ms-unsure 🔍
-6% - +3%
-3.38ms - +1.81ms
tip-of-tree
tip-of-tree
50.29ms - 54.29msunsure 🔍
-4% - +7%
-1.81ms - +3.38ms
-
emoji-picker-element-second-load
  • Browser: chrome-headless 127.0.6533.99
  • Sample size: 50
  • Built by: Benchmarks #464
  • Commit: fc58af5
VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
this-change
42.89ms - 45.08ms-unsure 🔍
-4% - +3%
-1.85ms - +1.23ms
tip-of-tree
tip-of-tree
43.21ms - 45.38msunsure 🔍
-3% - +4%
-1.23ms - +1.85ms
-

tachometer-reporter-action v2 for Benchmarks

github-actions[bot] commented 2 months ago

Size Change: +57 B (+0.16%)

Total Size: 36.4 kB

Filename Size Change
./bundle.js 36.4 kB +57 B (+0.16%)

compressed-size-action

nolanlawson commented 2 months ago

Had to bump up the CPU throttling to 20 and reduce auto sample condition to 1% to see the impact, but it is an improvement:

Click to see ``` ./test/benchmark/change-tab.tachometer.json Re-using git checkout: https://github.com/nolanlawson/emoji-picker-element.git#master /tmp/tachometer/versions/3e29c34f458a7f02a160e0f60aef088c5e5f0c00f24ba5dbd586c6f1db4d54a3 Re-using NPM install dir: /tmp/tachometer/versions/0cc70e69a5fe3d08fac07633318d157d8ebcc643026d2a6a7225828505bed31d [----------------------------------------------------------] launching chromeRunning benchmarks [==========================================================] done ┌─────────────┬─────────────────┐ │ Browser │ chrome-headless │ │ │ 127.0.6533.99 │ ├─────────────┼─────────────────┤ │ Sample size │ 100 │ └─────────────┴─────────────────┘ ┌─────────────┬─────────────┬────────────┬─────────────────────┬───────────────────┬───────────────────┐ │ Benchmark │ Version │ Bytes │ Avg time │ vs this-change │ vs tip-of-tree │ │ │ │ │ │ │ tip-of-tree │ ├─────────────┼─────────────┼────────────┼─────────────────────┼───────────────────┼───────────────────┤ │ this-change │ │ 860.32 KiB │ 375.50ms - 379.10ms │ │ faster │ │ │ │ │ │ - │ 8% - 10% │ │ │ │ │ │ │ 33.65ms - 39.94ms │ ├─────────────┼─────────────┼────────────┼─────────────────────┼───────────────────┼───────────────────┤ │ tip-of-tree │ tip-of-tree │ 859.73 KiB │ 411.51ms - 416.67ms │ slower │ │ │ │ │ │ │ 9% - 11% │ - │ │ │ │ │ │ 33.65ms - 39.94ms │ │ └─────────────┴─────────────┴────────────┴─────────────────────┴───────────────────┴───────────────────┘ ./test/benchmark/database-interactions.tachometer.json Re-using git checkout: https://github.com/nolanlawson/emoji-picker-element.git#master /tmp/tachometer/versions/3e29c34f458a7f02a160e0f60aef088c5e5f0c00f24ba5dbd586c6f1db4d54a3 Re-using NPM install dir: /tmp/tachometer/versions/0cc70e69a5fe3d08fac07633318d157d8ebcc643026d2a6a7225828505bed31d [----------------------------------------------------------] launching chromeRunning benchmarks [==========================================================] done ⠋ Auto-sample 50 (timeout in 3m6s) ┌─────────────┬─────────────────┐ │ Browser │ chrome-headless │ │ │ 127.0.6533.99 │ ├─────────────┼─────────────────┤ │ Sample size │ 150 │ └─────────────┴─────────────────┘ ┌─────────────┬─────────────┬────────────┬─────────────────────┬───────────────────┬───────────────────┐ │ Benchmark │ Version │ Bytes │ Avg time │ vs this-change │ vs tip-of-tree │ │ │ │ │ │ │ tip-of-tree │ ├─────────────┼─────────────┼────────────┼─────────────────────┼───────────────────┼───────────────────┤ │ this-change │ │ 860.41 KiB │ 938.25ms - 948.35ms │ │ unsure │ │ │ │ │ │ - │ -0% - +1% │ │ │ │ │ │ │ -4.58ms - +9.29ms │ ├─────────────┼─────────────┼────────────┼─────────────────────┼───────────────────┼───────────────────┤ │ tip-of-tree │ tip-of-tree │ 859.81 KiB │ 936.20ms - 945.70ms │ unsure │ │ │ │ │ │ │ -1% - +0% │ - │ │ │ │ │ │ -9.29ms - +4.58ms │ │ └─────────────┴─────────────┴────────────┴─────────────────────┴───────────────────┴───────────────────┘ ./test/benchmark/first-load.tachometer.json Re-using git checkout: https://github.com/nolanlawson/emoji-picker-element.git#master /tmp/tachometer/versions/3e29c34f458a7f02a160e0f60aef088c5e5f0c00f24ba5dbd586c6f1db4d54a3 Re-using NPM install dir: /tmp/tachometer/versions/0cc70e69a5fe3d08fac07633318d157d8ebcc643026d2a6a7225828505bed31d [----------------------------------------------------------] launching chromeRunning benchmarks [==========================================================] done ┌─────────────┬─────────────────┐ │ Browser │ chrome-headless │ │ │ 127.0.6533.99 │ ├─────────────┼─────────────────┤ │ Sample size │ 100 │ └─────────────┴─────────────────┘ ┌─────────────┬─────────────┬────────────┬─────────────────────┬──────────────────┬──────────────────┐ │ Benchmark │ Version │ Bytes │ Avg time │ vs this-change │ vs tip-of-tree │ │ │ │ │ │ │ tip-of-tree │ ├─────────────┼─────────────┼────────────┼─────────────────────┼──────────────────┼──────────────────┤ │ this-change │ │ 860.12 KiB │ 579.16ms - 590.11ms │ │ faster │ │ │ │ │ │ - │ 1% - 4% │ │ │ │ │ │ │ 8.29ms - 23.14ms │ ├─────────────┼─────────────┼────────────┼─────────────────────┼──────────────────┼──────────────────┤ │ tip-of-tree │ tip-of-tree │ 859.52 KiB │ 595.33ms - 605.36ms │ slower │ │ │ │ │ │ │ 1% - 4% │ - │ │ │ │ │ │ 8.29ms - 23.14ms │ │ └─────────────┴─────────────┴────────────┴─────────────────────┴──────────────────┴──────────────────┘ ./test/benchmark/search.tachometer.json Re-using git checkout: https://github.com/nolanlawson/emoji-picker-element.git#master /tmp/tachometer/versions/3e29c34f458a7f02a160e0f60aef088c5e5f0c00f24ba5dbd586c6f1db4d54a3 Re-using NPM install dir: /tmp/tachometer/versions/0cc70e69a5fe3d08fac07633318d157d8ebcc643026d2a6a7225828505bed31d [----------------------------------------------------------] launching chromeRunning benchmarks [==========================================================] done ┌─────────────┬─────────────────┐ │ Browser │ chrome-headless │ │ │ 127.0.6533.99 │ ├─────────────┼─────────────────┤ │ Sample size │ 100 │ └─────────────┴─────────────────┘ ┌─────────────┬─────────────┬────────────┬─────────────────────┬───────────────────┬───────────────────┐ │ Benchmark │ Version │ Bytes │ Avg time │ vs this-change │ vs tip-of-tree │ │ │ │ │ │ │ tip-of-tree │ ├─────────────┼─────────────┼────────────┼─────────────────────┼───────────────────┼───────────────────┤ │ this-change │ │ 860.41 KiB │ 260.63ms - 264.09ms │ │ faster │ │ │ │ │ │ - │ 16% - 18% │ │ │ │ │ │ │ 51.98ms - 57.24ms │ ├─────────────┼─────────────┼────────────┼─────────────────────┼───────────────────┼───────────────────┤ │ tip-of-tree │ tip-of-tree │ 859.82 KiB │ 314.99ms - 318.95ms │ slower │ │ │ │ │ │ │ 20% - 22% │ - │ │ │ │ │ │ 51.98ms - 57.24ms │ │ └─────────────┴─────────────┴────────────┴─────────────────────┴───────────────────┴───────────────────┘ ./test/benchmark/second-load.tachometer.json Re-using git checkout: https://github.com/nolanlawson/emoji-picker-element.git#master /tmp/tachometer/versions/3e29c34f458a7f02a160e0f60aef088c5e5f0c00f24ba5dbd586c6f1db4d54a3 Re-using NPM install dir: /tmp/tachometer/versions/0cc70e69a5fe3d08fac07633318d157d8ebcc643026d2a6a7225828505bed31d [----------------------------------------------------------] launching chromeRunning benchmarks [==========================================================] done ┌─────────────┬─────────────────┐ │ Browser │ chrome-headless │ │ │ 127.0.6533.99 │ ├─────────────┼─────────────────┤ │ Sample size │ 100 │ └─────────────┴─────────────────┘ ┌─────────────┬─────────────┬────────────┬─────────────────────┬───────────────────┬───────────────────┐ │ Benchmark │ Version │ Bytes │ Avg time │ vs this-change │ vs tip-of-tree │ │ │ │ │ │ │ tip-of-tree │ ├─────────────┼─────────────┼────────────┼─────────────────────┼───────────────────┼───────────────────┤ │ this-change │ │ 860.47 KiB │ 431.10ms - 438.57ms │ │ faster │ │ │ │ │ │ - │ 3% - 5% │ │ │ │ │ │ │ 11.90ms - 23.23ms │ ├─────────────┼─────────────┼────────────┼─────────────────────┼───────────────────┼───────────────────┤ │ tip-of-tree │ tip-of-tree │ 859.88 KiB │ 448.14ms - 456.66ms │ slower │ │ │ │ │ │ │ 3% - 5% │ - │ │ │ │ │ │ 11.90ms - 23.23ms │ │ └─────────────┴─────────────┴────────────┴─────────────────────┴───────────────────┴───────────────────┘ ```