Skip to content

vibe optimization#547

Merged
dcastil merged 14 commits intodcastil:mainfrom
quantizor:perf
Nov 2, 2025
Merged

vibe optimization#547
dcastil merged 14 commits intodcastil:mainfrom
quantizor:perf

Conversation

@quantizor
Copy link
Contributor

@quantizor quantizor commented Mar 16, 2025

Claude and I jammed on some potential improvements...

base base - best of 3
adjusted, size 500 cache 500 - best of 3

Rationale for increasing cache size is the partials it's storing are quite small and a medium-complexity website may have thousands of them. They probably won't take up much space even in volume.

Roughly a 9% improvement in the cached example and 11% overall in the heavy case.

@github-actions github-actions bot added the context-v3 Related to tailwind-merge v3 label Mar 16, 2025
@dcastil
Copy link
Owner

dcastil commented Mar 21, 2025

Hey @quantizor, thanks for optimizing the runtime!

Just took a brief look at the diff and I think it would be good to split this into multiple PRs so I can verify some changes in isolation. If you're up to it, I'll review your changes in more detail tomorrow, probably leave a bunch of comments and let you know how to best split it up.

@quantizor
Copy link
Contributor Author

Hey @quantizor, thanks for optimizing the runtime!

Just took a brief look at the diff and I think it would be good to split this into multiple PRs so I can verify some changes in isolation. If you're up to it, I'll review your changes in more detail tomorrow, probably leave a bunch of comments and let you know how to best split it up.

Sure thing!

Copy link
Owner

@dcastil dcastil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool stuff! I added some comments around some details. At the scale of tailwind-merge it makes sense to pay attention to every small thing to not introduce potential regressions.

@quantizor quantizor mentioned this pull request Sep 1, 2025
@quantizor
Copy link
Contributor Author

@dcastil updated per your suggestions

@quantizor quantizor requested a review from dcastil September 1, 2025 03:46
Copy link
Owner

@dcastil dcastil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @quantizor, thanks for the really long wait!

Thanks for addressing all the comments. I added a few commits fixing some minor things as well, hope you don't mind.

I checked everything and it looks good, I could also verify the speed improvements. 👍 There is just one thing in sort-modifiers.ts we should address before merging (#547 (comment)). Could you take a look at it?

After addressing it I consider this to be ready for merge. 🙂

@quantizor
Copy link
Contributor Author

Bench results after tweaks:

OLD

 ✓ tests/tw-merge.benchmark.ts > twMerge 3061ms
     name                            hz     min      max     mean      p75      p99     p995     p999     rme  samples
   · init                      4,210.32  0.2087   2.7886   0.2375   0.2364   0.5238   0.5781   0.9083  ±1.45%     2106
   · simple                    4,499.52  0.2101   0.5602   0.2222   0.2208   0.3823   0.3990   0.4524  ±0.54%     2250   fastest
   · heavy                     4,086.20  0.2217   2.6981   0.2447   0.2420   0.4962   0.5524   0.6520  ±1.25%     2044
   · collection with cache       608.18  1.4067   7.9597   1.6442   1.5477   5.7333   7.4706   7.9597  ±4.68%      305
   · collection without cache   98.5241  9.5441  10.7708  10.1498  10.4183  10.7708  10.7708  10.7708  ±0.93%       50   slowest

NEW

 ✓ tests/tw-merge.benchmark.ts > twMerge 3054ms
     name                            hz     min      max    mean     p75      p99     p995     p999     rme  samples
   · init                      4,620.76  0.1933   1.3782  0.2164  0.2208   0.3966   0.5028   1.0336  ±1.04%     2311
   · simple                    4,840.87  0.1938   0.5355  0.2066  0.2077   0.3755   0.3942   0.4328  ±0.48%     2421   fastest
   · heavy                     4,616.99  0.2045   0.4501  0.2166  0.2178   0.3655   0.3987   0.4243  ±0.43%     2309
   · collection with cache       724.81  1.2980   3.5978  1.3797  1.3907   1.7990   2.0750   3.5978  ±1.09%      363
   · collection without cache    103.79  8.9342  19.0420  9.6348  9.5288  19.0420  19.0420  19.0420  ±4.38%       52   slowest

@quantizor
Copy link
Contributor Author

quantizor commented Oct 29, 2025

Best of 3 with memory info from #620

main branch

Memory Usage Summary:
  init: 1.57 MB heap
  simple: 1016.39 KB heap
  heavy: 1.01 MB heap
  collection with cache: 2.52 MB heap
    Total footprint: 234.75 MB
    Operations: 1322
  collection without cache: 16.99 MB heap
    Total footprint: 235.13 MB
    Operations: 1322


 ✓ tests/tw-merge.benchmark.ts > twMerge 3136ms
     name                            hz     min      max    mean     p75      p99     p995     p999     rme  samples
   · init                      4,065.35  0.2175   1.8490  0.2460  0.2450   0.4969   0.5517   0.8136  ±1.12%     2033
   · simple                    4,062.11  0.2270   0.7383  0.2462  0.2448   0.4628   0.4756   0.5714  ±0.70%     2032
   · heavy                     3,837.87  0.2374   2.3023  0.2606  0.2597   0.4791   0.5047   0.8659  ±1.06%     1919
   · collection with cache       688.97  1.3773   2.2432  1.4514  1.4654   1.7979   1.9276   2.2432  ±0.68%      345
   · collection without cache    109.09  8.8340  10.2709  9.1664  9.2940  10.2709  10.2709  10.2709  ±0.73%       55

perf branch

Memory Usage Summary:
  init: 1.22 MB heap
  simple: 838.82 KB heap
  heavy: 647.81 KB heap
  collection with cache: 1.79 MB heap
    Total footprint: 171.70 MB
    Operations: 1322
  collection without cache: 13.72 MB heap
    Total footprint: 238.06 MB
    Operations: 1322


 ✓ tests/tw-merge.benchmark.ts > twMerge 3130ms
     name                            hz     min      max    mean     p75      p99     p995     p999     rme  samples
   · init                      4,581.74  0.1975   1.3568  0.2183  0.2220   0.3657   0.4523   0.6930  ±0.89%     2291
   · simple                    4,396.86  0.2133   0.5638  0.2274  0.2274   0.4307   0.4576   0.5137  ±0.55%     2199
   · heavy                     4,182.74  0.2232   0.5723  0.2391  0.2393   0.4502   0.4675   0.5242  ±0.58%     2092
   · collection with cache       724.98  1.3007   3.3782  1.3793  1.4092   1.6660   2.2602   3.3782  ±1.02%      363
   · collection without cache    110.72  8.6614  10.1187  9.0318  9.2184  10.1187  10.1187  10.1187  ±1.10%       56

@codspeed-hq
Copy link

codspeed-hq bot commented Nov 2, 2025

CodSpeed Performance Report

Merging #547 will improve performances by 19.21%

Comparing quantizor:perf (16f0482) with main (db06f11)

Summary

⚡ 4 improvements
✅ 1 untouched

Benchmarks breakdown

Benchmark BASE HEAD Change
collection with cache 19.2 ms 17.2 ms +11.56%
heavy 5 ms 4.2 ms +18.89%
init 5.7 ms 5 ms +13.45%
simple 4.7 ms 3.9 ms +19.21%

@dcastil
Copy link
Owner

dcastil commented Nov 2, 2025

Just noting here:

Size of total ESM bundle increased from 6.68 kB to 6.96 kB minified + Brotli-compressed which is a 4.2% increase. I think this is fine for the 10-20% perf boost.

Copy link
Owner

@dcastil dcastil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Great work, thanks!

@dcastil dcastil merged commit 660b993 into dcastil:main Nov 2, 2025
5 checks passed
@dcastil dcastil added the feature Is new feature label Nov 2, 2025
@github-actions
Copy link

github-actions bot commented Nov 9, 2025

This was addressed in release v3.4.0.

Repository owner deleted a comment from github-actions bot Feb 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

context-v3 Related to tailwind-merge v3 feature Is new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments