alexeyraspopov / picocolors

The tiniest and the fastest library for terminal output formatting with ANSI colors
ISC License
1.34k stars 44 forks source link

Add bechmarks for chalk 5 and yoctocolors #61

Closed prantlf closed 2 weeks ago

prantlf commented 8 months ago

Fixes #45.

Changes

The latest version of chalk does not support CJS, but it is possible to bundle it in the CJS format. It is worth testing the latest available version.

yoctocolors does not support CJS, but it is possible to bundle it in the CJS format. This library aspires to be the new tiniest one. It supports FORCE_COLOR and NO_COLOR too. It is worth comparing it to picocolors.

Split chalk to chalk4 and chalk5 using NPM module aliases. Also upgrade development dependencies. Keep the same major version of clean-publish not to break the legacy Node.js tests.

Use esbuild to create CJS bundles of chalk5 and yoctocolors. Add chalk5 and yoctocolors to every benchmark. Rename the former chalk tests to chalk4.

Results

The simple.js benchmark shows 5% decrease of performance in chalk 5 against chalk 4. yoctocolors beat picocolors by 284%.

❯ node benchmarks/simple.js
colorette
kleur
chalk5
chalk4
ansi
cliColor
picocolors
nanocolors
yoctocolors
  chalk5         26,287,893 ops/sec
  chalk4         25,221,564 ops/sec
  cli-color       1,412,525 ops/sec
  ansi-colors     6,463,786 ops/sec
  kleur          26,363,857 ops/sec
  kleur/colors   52,166,754 ops/sec
  colorette      50,574,214 ops/sec
  nanocolors     51,646,373 ops/sec
  yoctocolors   195,458,649 ops/sec
+ picocolors     50,840,902 ops/sec

The complex.js benchmark shows 3% decrease of performance in chalk 5 against chalk 4. yoctocolors beat picocolors by 61%.

❯ node benchmarks/complex.js
  chalk5          1,178,597 ops/sec
  chalk4          1,215,094 ops/sec
  cli-color         152,419 ops/sec
  ansi-colors       558,016 ops/sec
  kleur           1,251,816 ops/sec
  kleur/colors    1,523,289 ops/sec
  colorette       1,813,436 ops/sec
  nanocolors      1,682,924 ops/sec
  yoctocolors     4,424,045 ops/sec
+ picocolors      2,747,818 ops/sec

The loading.js benchmark shows 44% decrease of performance in chalk 5 against chalk 4. yoctocolors is 75% slower than picocolors. I tried replacing the color detection in yoctocolors with the code from picocolors and the loading time went down to 0.588 ms, 52% slower than picocolors.

❯ node benchmarks/loading.js
  chalk5         7.713 ms
  chalk4         5.372 ms
  cli-color     32.428 ms
  ansi-colors    1.420 ms
  kleur          2.345 ms
  kleur/colors   0.960 ms
  colorette      0.887 ms
  nanocolors     0.708 ms
  yoctocolors    0.679 ms
+ picocolors     0.388 ms

The size.js benchmark shows 57% size reduction for chalk 5 against chalk 4. yoctocolors is practically the same as picocolors. This benchmark isn't reliable, because the size of the actually used code may be much smaller, as the comparison of the single-file libraries yoctocolors and picocolors shows.

❯ node benchmarks/size.js
Data from packagephobia.com
  chalk@5.3.0  43 kB
  chalk@4.1.2 101 kB
  cli-color   796 kB
  ansi-colors  27 kB
  kleur        20 kB
  colorette    17 kB
  nanocolors   15 kB
  yoctocolors   7 kB
+ picocolors    7 kB

❯ minified-size picocolors.js
picocolors.js: 2.6 kB, 1.86 kB, 626 B, 528 B

❯ minified-size benchmarks/yoctocolors.js
benchmarks/yoctocolors.js: 2.92 kB, 1.82 kB, 789 B, 697 B```
alexeyraspopov commented 7 months ago

Thank you for taking time to contribute!

I will need a bit more time to thoroughly review the changes, apologies for the delay.

The very least I can say is that the decision to drop Node.js v6 should not be in the scope of this PR. This is something better be done in a separate PR and dropping anything below v10.16 would allow us to simplify color detection by a lot. Most likely a breaking change, so we gotta check if the largest user would be okay with it moving forward cc @ai

Another thing I'd like to point out is that yoctocolors is not a serious package to keep alongside others. At the very least, it's not complete. See how the code snippets from complex benchmark work:

image

Let's remove yoctocolors from benchmarks.

ai commented 7 months ago

dropping anything below v10.16 would allow us to simplify color detection by a lot. Most likely a breaking change, so we gotta check if the largest user would be okay with it moving forward cc @ai

Browserslist supports Node.js 6 and releasing new major is very painful for the project.

But I think I can just avoid requiring picocolors on old Node.js versions in Browserslist. Anyway it is too old version.

sindresorhus commented 5 months ago

Another thing I'd like to point out is that yoctocolors is not a serious package to keep alongside others. At the very least, it's not complete.

It is now: https://github.com/sindresorhus/yoctocolors/releases/tag/v2.0.1