Skip to content

Poor performance of space-* classes (:where(& > :not(:last-child))) #18804

@nathanael-ruf

Description

@nathanael-ruf

What version of Tailwind CSS are you using?

4.1.12

What build tool (or framework if it abstracts the build tool) are you using?

Vite 6.3.5

What version of Node.js are you using?

22.15.0

What browser are you using?

Chrome

What operating system are you using?

macOS

Reproduction URL

I tried to reproduce in Tailwind Play, but it seems like that it not actually using tailwind v4 if v4 is selected. If you check the generated css file in the browser on that page it includes

! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com

I hence cannot provide a tailwind play link (bug it not reproducible in v3, because the generated selectors are different)

If I'm wrong about the above, let me know and I'll try again.

Describe your issue

All the space-* classes (like space-y-1) result in css like this

.space-y-1 {
    :where(& > :not(:last-child)) {
        --tw-space-y-reverse: 0;
        margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));
        margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)));
    }
}

The problem is that this selector :where(& > :not(:last-child)) is expensive for the browser to evaluate/match.
I have a relatively large DOM (a codemirror editor with file open that has many long lines, a real world example could be a javascript bundle file) and a single recalculate style run takes ~50ms for me which (if a few are triggered) can cause a noticeable delay on user action.

With "enable css selector stats" chrome reports

Image

so the space selectors take up the largest chunk (there are other issues that I'm solving separately, the second one is another tailwind generated css selector, but that one I use only once and can just avoid).

Another note: There are 403875 match attempts, but "only" 26925 elements affected (dom size). 403875/26925 is exactly 15 and 15 is the number of different space-* classes I use in my project.

I know that the performance of recalculate style depends on selectors and dom size, but since I can't realistically reduce the dom size (codemirror already has virtualized scrolling), I thought I'll ask here to see if anyone has an idea for a more performant selector for the space classes.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions