daisyui icon indicating copy to clipboard operation
daisyui copied to clipboard

bug: performance issue with select + checkbox

Open michaelkhabarov opened this issue 10 months ago โ€ข 17 comments

Reproduction URL (Required)

https://michaelkhabarov.github.io/daisyui-performance-issue/

What version of daisyUI are you using?

v5.0.27

Which browsers are you seeing the problem on?

Chrome

Describe your issue

Hello

I am experiencing a performance issue with DaisyUI using the following simple HTML:

<html>
  <head>
    <link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
    <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
  </head>
  <body>
    <!-- removing this select fixes issue -->
    <select></select>

    <label>Checkbox: <input type="checkbox" /></label>

    <script>
      content = ""
      for (let i = 0; i < 3000; i++) {
        content += `<div class="btn">Btn</div>`
      }
      document.body.innerHTML += content
    </script>
  </body>
</html>

Clicking the checkbox takes approximately 150 ms to process, and about 500 ms with a 4x CPU slowdown. This action triggers a repaint of the entire page, including all 3000 .btn elements. The more elements on the page, the slower the performance becomes.

Image

Removing the select tag completely resolves the issue, reducing the checkbox selection time to around 50 ms and repainting only the checkbox itself.

This issue is reproducible on Chrome for macOS M1 v135.0.7049.96, but not on Chrome for Linux v132.0.6834.110. So, Iโ€™m not sure if this is entirely a DaisyUI issue

michaelkhabarov avatar Apr 21 '25 14:04 michaelkhabarov

Thank you @michaelkhabarov for reporting issues. It helps daisyUI a lot ๐Ÿ’š
I'll be working on issues one by one. I will help with this one as soon as a I find a solution.
In the meantime providing more details and reproduction links would be helpful.

github-actions[bot] avatar Apr 21 '25 14:04 github-actions[bot]

This might be because of :root:has(input.theme-controller[value=dark]:checked) selector.

Are you also experiencing a lag with devtools closed? or on a real app? I assume 4x slower than M1 would be a ~2015 Macbook airโ€ฆ

saadeghi avatar Apr 21 '25 17:04 saadeghi

@michaelkhabarov @saadeghi I was about to open the same issue. I'm using AG Grid, and I've noticed a visible performance drop โ€” especially with row highlighting on hover (cpu goes > 140)โ€” when there's a select component on the page.

If I either disable the DaisyUI plugin or remove the select component, AG Grid works smoothly without any lag during hover. (cpu < 30)

dkhp03 avatar Apr 21 '25 22:04 dkhp03

This might be because of :root:has(input.theme-controller[value=dark]:checked) selector.

Removing this selector from final bundle does not help

Are you also experiencing a lag with devtools closed? or on a real app?

Yes, we have a relatively big page with around 20,000 DOM elements in production. Clicking on checkbox takes about a second with devtools closed and without CPU slowdown. Also tried in incognito tab - same result

We also encountered this issue in DaisyUI v4.12.23

michaelkhabarov avatar Apr 22 '25 11:04 michaelkhabarov

I also experienced a similar issue with DaisyUI and ag-grid table.

It's the "Recalculate Styles" that is taking all the time. A sample from dev-tools with css-selectors enabled for one "Recalculate Styles":

Elapsed (ms) Match attempts Match count % of slow-path non-matches Selector Style Sheet
140.051 101548 8652 47.1 (Totals for all selectors)
5.359 3948 0 85.7 & > * Unable to link via style-sheet-1326118-640
5.271 3948 0 85.7 & > * Unable to link via style-sheet-1326118-641
4.801 3384 0 0.0 &:nth-child(2) Unable to link via style-sheet-1326118-640
4.701 3384 0 0.0 &:nth-child(2) Unable to link via style-sheet-1326118-641
3.889 2820 0 0.0 &:nth-child(1) Unable to link via style-sheet-1326118-641
3.853 2820 0 0.0 &:nth-child(1) Unable to link via style-sheet-1326118-640
3.292 2256 6 0.0 :where(& > :not(:last-child)) Unable to link via style-sheet-1326118-640
3.244 2256 6 0.0 :where(& > :not(:last-child)) Unable to link via style-sheet-1326118-641
2.402 1718 18 0.0 &::before Unable to link via style-sheet-1326118-641
2.372 1718 18 0.0 &::before Unable to link via style

vish9812 avatar Apr 23 '25 18:04 vish9812

I'm working on it.
Apparently the repaint is because of a shared CSS variable --fx-noise used in different elements. That can be fixed by putting the value in each element repeatedly instead of using a global variable and it would fix the unnecessary repaint issue.

However that doesn't effect INP. Looks like using less CSS properties for button decreases the INP, but that's not an option since all the used properties are necessary.

I will try more things.

saadeghi avatar Apr 25 '25 09:04 saadeghi

We're also experiencing a major drop in performance with Chrome (also Edge) when using the class select.

Started commenting out CSS until I discovered that when removing these lines from the class select the drop in performance issue was fixed:

    @supports (appearance: base-select) {
      appearance: base-select;
    }
    @supports (appearance: base-select) {
      &::picker(select) {
        appearance: base-select;
      }
    }
 "daisyui": "^5.1.13",

Drelekin avatar Sep 18 '25 07:09 Drelekin

I had the same problem.

@Drelekin's alternative didn't work. Maybe I did it wrong or something else.

So the solution I found was to avoid using and use https://daisyui.com/components/dropdown/

"daisyui": "^5.3.10",

intelmib avatar Oct 28 '25 06:10 intelmib

We've also been seeing the performance issues with style recalculations since 5.1.0

Doesn't seem related to any specific components being on screen, but performance of even simple animations (anything that causes a style recalculation) is pretty much unusable

lewisdoesstuff avatar Nov 03 '25 12:11 lewisdoesstuff

Can you pinpoint the version that has problems at 5.1.0? I mean with 5.0.55 it was ok and with 5.1.0 the problems showed up? I need the info to try to identify the change

pdanpdan avatar Nov 03 '25 14:11 pdanpdan

That'll be a little tricky as my work uses an internal npm repo so I only have 5.1.0 and 5.0.0 available

I'll get a test project at home tomorrow and bisect through to narrow it down

lewisdoesstuff avatar Nov 03 '25 16:11 lewisdoesstuff

Yes, please, of you can it would help because you can identify better when the problem happens

BTW, skip checking 5.0.55 (it's the same as 5.1.0), check 5.054 and before (if it's already present in 5.1.0)

pdanpdan avatar Nov 03 '25 16:11 pdanpdan

I've put together a simple Vue app that moves cards around with a TransitionGroup to replicate this: daisyui-perf-test

While the performance here is pretty okay across all versions (as it's a simple app), there is a significant increase in CSS selector times at 5.0.30 and at 5.0.32

Full results are in results/ with the complete CSS selector stats, but the totals for each version I tested are:

Version Time Diff (ms) Diff %
5.0.0 (baseline) 7.259 0 0.00%
5.0.25 7.489 + 0.23 + 3.17%
5.0.28 7.905 + 0.646 + 8.90%
5.0.29 7.669 + 0.41 + 5.65%
5.0.30 9.287 + 2.028 + 27.94%
5.0.31 9.67 + 2.411 + 33.21%
5.0.32 12.401 + 5.142 + 70.84%
5.0.35 12.022 + 4.763 + 65.62%
5.0.55 12.651 + 5.392 + 74.28%
5.1.0 12.433 + 5.174 + 71.28%
5.4.3 12.599 + 5.34 + 73.56%

Tested on an M2 Macbook Air, Chrome 141

lewisdoesstuff avatar Nov 04 '25 18:11 lewisdoesstuff

This doesn't seem to make sense:

5.0.29->5.0.30: modified the matches on .tooltip, but it should be already qualified by .tooltip and you don't have any 5.0.31->5.0.32: added a touch-action: manipulation on .btn and the increase in time is 33%

pdanpdan avatar Nov 04 '25 18:11 pdanpdan

@pdanpdan There's tooltip in the card that was used for benchmark src/components/TestCard.vue

@lewisdoesstuff Thanks for the benchmark repo. The added selectors (which uses CSS :has() or the touch-action: manipulation in button) are required, and they are not decorative.
It is expected for CSS :has() selector to have relatively lower performance than a .classname selector because browsers need to check the children. But this shouldn't be an issue, since a browser is way more faster than that in rendering.

Maybe we can find a way to help if you share a real-life example of the situation.
For example if there's a need for 100 cards to have animations, maybe using a tooltip inside them is not worth it ๐Ÿ˜…

saadeghi avatar Nov 04 '25 20:11 saadeghi

Sorry, I missed the tooltip, so for 29->30 it is reasonable, but why the huge difference between 31 and 32 which should be very similar

pdanpdan avatar Nov 04 '25 20:11 pdanpdan

Thanks guys, I'll try and put together a more real-world example tomorrow, as I've noticed this when doing things other than list animations

lewisdoesstuff avatar Nov 04 '25 21:11 lewisdoesstuff