Skip to content

perf(css): bucket .pagination universal * subject by child tag - #3079

Merged
jonrohan merged 2 commits into
mainfrom
copilot/perf-css-primer-view-components-selectors
Jun 17, 2026
Merged

perf(css): bucket .pagination universal * subject by child tag#3079
jonrohan merged 2 commits into
mainfrom
copilot/perf-css-primer-view-components-selectors

Conversation

CopilotAI commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

What are you trying to accomplish?

Primer-owned selectors with a universal subject compound (* / :not([attr])) can't be bucketed by Blink, so they run the full matcher against (nearly) every element on every style recalc — pure wasted work. In @primer/css, the only such offender is .pagination > * (the responsive show/hide rules).

What approach did you choose and why?

  • src/pagination/pagination.scss — replaced the two .pagination > * rules with tag-bucketed selectors so the engine can fast-reject:

    // before
    > * { display: none; }
    // after — buckets on the tags the component already styles
    > a,
    > span,
    > em { display: none; }

    Output is unchanged: the overriding show-rules (> :first-child, > .current, …) keep higher specificity (0,2,0) than the new hide rule (0,1,1), so the responsive cascade is preserved.

  • Added a changeset (patch).

Scope notes:

  • The remaining tracking-issue offenders (.autocomplete-item, .Popover-message, .breadcrumb-item, .ActionListItem*, .FormControl-*, .prc-*) live in @primer/view-components / @primer/react, not here.
  • The :is() list-merge root cause does not apply to @primer/css: SCSS emits expanded per-selector rules, and the compiled dist/primer.css contains zero :is(.

What should reviewers focus on?

  • Whether .pagination direct children are always a / span / em (consistent with the existing a, span, em styling block). Any other child type would no longer be hidden by the default rule.
  • The structural-pseudo selectors (> :first-child, > :nth-child(2), …) were intentionally left unchanged — they aren't */:not([attr]) subjects per the issue, and rewriting them is invasive without addressing the called-out root causes.

Can these changes ship as is?

  • Yes, this PR does not depend on additional changes. 🚢

@changeset-bot

changeset-botBot commented Jun 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1c684c0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@primer/cssPatch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

CopilotAI changed the title [WIP] Fix upstream Primer-owned selectors affecting style recalcsperf(css): bucket .pagination universal * subject by child tagJun 17, 2026
CopilotAI requested a review from mattcosta7June 17, 2026 14:23
@mattcosta7
mattcosta7 marked this pull request as ready for review June 17, 2026 14:53
@mattcosta7
mattcosta7 requested review from a team as code ownersJune 17, 2026 14:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Ready to approve

The selector changes are narrowly scoped, preserve the intended responsive cascade via specificity/order, and align with the component’s existing a/span/em child styling.

Note: this review does not count toward required approvals for merging.

Pull request overview

This PR improves selector-matching performance in the pagination component by replacing unbucketable universal-child selectors (.pagination > *) with tag-bucketed selectors so Blink can more quickly reject non-matching elements during style recalculation.

Changes:

  • Replaced .pagination > * responsive hide/show rules with > a, > span, > em equivalents in src/pagination/pagination.scss.
  • Added a patch changeset documenting the performance-motivated selector change.
File summaries
FileDescription
src/pagination/pagination.scssReplaces universal direct-child selectors with tag-bucketed a/span/em selectors for improved Blink matching performance.
.changeset/pagination-universal-subject-perf.mdAdds a patch changeset explaining the selector change and why it improves performance without changing output.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jonrohan
jonrohan merged commit d735d75 into mainJun 17, 2026
18 checks passed
@jonrohan
jonrohan deleted the copilot/perf-css-primer-view-components-selectors branch June 17, 2026 16:30
@primerprimerBot mentioned this pull request Jun 17, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@jonrohan@francinelucca@mattcosta7