classnames icon indicating copy to clipboard operation
classnames copied to clipboard

Refactored index.js to reduce size by 30-70%

Open Ben-Brady opened this issue 8 months ago • 1 comments

Refactored index.js to reduce bundle size whilst keeping performance

  • Changed final condition check in parseValue into an expression
    • this allows the entire function to be turned into an inlined expression
    • inlined this into the top function
  • swapped from accumilators to map and joins
    • by using expressions instead, bundlers can inline more code
  • removed parseValue
    • it was only used it one place and the classNames function was 3 lines before changes
  • removed appendClass
    • after reworking everything I realised I was only using it a single place and it no longer made sense to use
  • swapped to ..args instead of arguments
    • args is an array by default, meaning we can use .map without any additional steps
    • we don't have to convert it to an array or do a for loop
  • removed typeof arg !== "object" check
    • the !arg covers

Bundle Size

When compiled using microbundle in isolation:

Original:

308 B: classnames.js.gz
254 B: classnames.js.br

New Version:

218 B: classnames.js.gz
178 B: classnames.js.br

When built into an actual project I created an empty preact project using npm create vite to get the build difference in an actual project

No classNames: 11,372 (gzip: 4,820) ./dist/assets/index-CGD-ssac.js Original: 12,262 (gzip: 5,220) ./dist/assets/index-D8rnffc0.js New Version: 11,671 (gzip: 4,940) ./dist/assets/index-hh12ETg_.js

Uncompressed(33%): +890 -> +299 Gzip(30%): +400 -> +120

Note: I think the difference is so big is because the inability to convert into a tunary is really expensive in this case

Benchmark Results

Performance appears unchanged

Benchmarking 'strings'.

| Task name | Latency avg (ns) | Latency med (ns) | Throughput avg (ops/s) | Throughput med (ops/s) | Samples |
| --------- | ---------------- | ---------------- | ---------------------- | ---------------------- | ------- |
| reworked  | 121.51 ± 0.19%   | 111.00 ± 1.00    | 8587128 ± 0.01%        | 9009009 ± 81900        | 8229759 |
| original  | 123.50 ± 0.13%   | 120.00 ± 9.00    | 8440112 ± 0.01%        | 8333333 ± 675676       | 8097160 |

Benchmarking 'object'.

| Task name | Latency avg (ns) | Latency med (ns) | Throughput avg (ops/s) | Throughput med (ops/s) | Samples |
| --------- | ---------------- | ---------------- | ---------------------- | ---------------------- | ------- |
| reworked  | 123.12 ± 1.14%   | 110.00 ± 0.00    | 8552463 ± 0.01%        | 9090909 ± 0            | 8122470 |
| original  | 120.44 ± 0.12%   | 111.00 ± 1.00    | 8594657 ± 0.01%        | 9009010 ± 81900        | 8303130 |

Benchmarking 'strings, object'.

| Task name | Latency avg (ns) | Latency med (ns) | Throughput avg (ops/s) | Throughput med (ops/s) | Samples |
| --------- | ---------------- | ---------------- | ---------------------- | ---------------------- | ------- |
| reworked  | 153.61 ± 0.17%   | 141.00 ± 1.00    | 6776792 ± 0.01%        | 7092199 ± 50659        | 6509904 |
| original  | 154.21 ± 0.16%   | 150.00 ± 9.00    | 6727520 ± 0.01%        | 6666667 ± 425532       | 6484668 |

Benchmarking 'mix'.

| Task name | Latency avg (ns) | Latency med (ns) | Throughput avg (ops/s) | Throughput med (ops/s) | Samples |
| --------- | ---------------- | ---------------- | ---------------------- | ---------------------- | ------- |
| reworked  | 233.67 ± 0.68%   | 211.00 ± 1.00    | 4543994 ± 0.01%        | 4739336 ± 22568        | 4279555 |
| original  | 237.36 ± 0.88%   | 221.00 ± 1.00    | 4436742 ± 0.01%        | 4524887 ± 20568        | 4213018 |

Benchmarking 'arrays'.

| Task name | Latency avg (ns) | Latency med (ns) | Throughput avg (ops/s) | Throughput med (ops/s) | Samples |
| --------- | ---------------- | ---------------- | ---------------------- | ---------------------- | ------- |
| reworked  | 375.24 ± 0.11%   | 361.00 ± 1.00    | 2730653 ± 0.01%        | 2770083 ± 7695         | 2664987 |
| original  | 373.86 ± 0.12%   | 361.00 ± 10.00   | 2743952 ± 0.01%        | 2770083 ± 78920        | 2674781 |

Ben-Brady avatar May 06 '25 21:05 Ben-Brady