Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
190058f
simple improvements
mattcosta7 Nov 26, 2025
44a815c
adds a queuing structure for raf throttling updates
mattcosta7 Nov 26, 2025
3cf401a
update body flag writing
mattcosta7 Nov 26, 2025
d25aaf1
Initial plan
Copilot Nov 27, 2025
63599b8
Use setPointerCapture for drag and optimize width updates during mous…
Copilot Nov 27, 2025
cee9442
Fix race condition in drag delta tracking by using ref
Copilot Nov 27, 2025
f245cd8
Use GPU-accelerated transforms for drag preview instead of width updates
Copilot Nov 28, 2025
219306b
Remove width from will-change since only transforms are used during drag
Copilot Nov 28, 2025
296ef29
Use direct DOM style manipulation for drag delta to avoid React re-re…
Copilot Nov 28, 2025
79685a9
Refactor: Extract CSS variable constant and helper function for delta…
Copilot Nov 28, 2025
e9d5f67
Use useImperativeHandle for ref synchronization instead of ref swapping
Copilot Nov 28, 2025
af4e09f
Simplify drag performance improvements
Copilot Nov 28, 2025
340d3b5
Fix flush/cancel order in drag handlers
Copilot Nov 28, 2025
8f75d75
simplify stable
mattcosta7 Nov 28, 2025
b86736a
simplify stable
mattcosta7 Nov 28, 2025
b069bfd
simplify stable
mattcosta7 Nov 28, 2025
c670f5f
simplify stable
mattcosta7 Nov 28, 2025
f71c9b0
simplify stable
mattcosta7 Nov 28, 2025
1b63444
frame
mattcosta7 Nov 28, 2025
8f9d1e5
constrain
mattcosta7 Nov 28, 2025
24ff5c5
mcss
mattcosta7 Nov 28, 2025
24ba053
smoother
mattcosta7 Nov 28, 2025
7770e63
updates
mattcosta7 Nov 28, 2025
80270a7
updates
mattcosta7 Nov 28, 2025
f165dd9
progressive fps
mattcosta7 Nov 28, 2025
6570bf3
update snapshots
mattcosta7 Nov 29, 2025
d4a7091
simplify a bit
mattcosta7 Nov 29, 2025
9782183
deop some unnecessary complexity
mattcosta7 Nov 30, 2025
fca99fe
deop some unnecessary complexity
mattcosta7 Nov 30, 2025
f190a07
improve a11y
mattcosta7 Nov 30, 2025
8d17ef7
improve perf
mattcosta7 Nov 30, 2025
d509a6b
more perf, less css reading
mattcosta7 Nov 30, 2025
4895a60
Update packages/react/src/PageLayout/PageLayout.tsx
mattcosta7 Nov 30, 2025
b21f28d
slight improvement
mattcosta7 Dec 1, 2025
585a67b
fix up some diff
mattcosta7 Dec 1, 2025
591e9ac
use-data-dragging instead of `isDragging`
mattcosta7 Dec 1, 2025
473e3f3
undo feature story change
mattcosta7 Dec 1, 2025
ccb20a8
perf story
mattcosta7 Dec 1, 2025
5de4de9
monitor
mattcosta7 Dec 1, 2025
d45b8c1
update
mattcosta7 Dec 1, 2025
f99ff5f
transition
mattcosta7 Dec 1, 2025
ce2d7cc
transition
mattcosta7 Dec 1, 2025
0cb267b
update pane width in effect
mattcosta7 Dec 1, 2025
1b68517
update pane width in effect
mattcosta7 Dec 1, 2025
8826fcc
pane width subscription
mattcosta7 Dec 1, 2025
3aff251
improve keyboard interaction
mattcosta7 Dec 1, 2025
d054588
improve keyboard interaction
mattcosta7 Dec 1, 2025
e1ff076
avoid name
mattcosta7 Dec 1, 2025
9dae955
comment
mattcosta7 Dec 1, 2025
4656eda
update css
mattcosta7 Dec 1, 2025
103c571
Merge branch 'main' into mc/copilot/sub-pr-7248
mattcosta7 Dec 1, 2025
bc5555c
changeset
mattcosta7 Dec 1, 2025
8fe1364
fix containment
mattcosta7 Dec 1, 2025
807e33a
Merge branch 'main' into mc/copilot/sub-pr-7248
mattcosta7 Dec 1, 2025
9a4003d
Merge branch 'main' into mc/copilot/sub-pr-7248
mattcosta7 Dec 1, 2025
3b04f70
remove onDragStart
mattcosta7 Dec 1, 2025
17fc2b5
backout test
mattcosta7 Dec 1, 2025
0c8bf15
Update packages/react/src/PageLayout/PageLayout.module.css
mattcosta7 Dec 1, 2025
22cfbf8
aat
mattcosta7 Dec 1, 2025
c8e7a06
aat
mattcosta7 Dec 1, 2025
94ef9c9
aat
mattcosta7 Dec 1, 2025
269155c
aat fix
mattcosta7 Dec 1, 2025
9d01862
handle frames softer
mattcosta7 Dec 1, 2025
dac73d2
remove perf header
mattcosta7 Dec 1, 2025
e93ccff
update snapshots
mattcosta7 Dec 1, 2025
66230cf
shave a few bytes on the handle checks
mattcosta7 Dec 1, 2025
bf13da9
cleanup a few bytes
mattcosta7 Dec 1, 2025
186ebc9
avoid heavy tests
mattcosta7 Dec 1, 2025
0029dfe
avoid heavy tests
mattcosta7 Dec 2, 2025
6844efd
fix vrt?
mattcosta7 Dec 2, 2025
e193e7d
Merge remote-tracking branch 'origin/main' into mc/copilot/sub-pr-7248
mattcosta7 Dec 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/olive-heads-enter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
---

Improve drag performance for PageLayout
2 changes: 2 additions & 0 deletions e2e/components/Axe.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const SKIPPED_TESTS = [
'components-flash-features--with-icon-action-dismiss', // TODO: Remove once color-contrast issues have been resolved
'components-flash-features--with-icon-and-action', // TODO: Remove once color-contrast issues have been resolved
'components-filteredactionlist--default',
'components-pagelayout-performance-tests--medium-content',
'components-pagelayout-performance-tests--heavy-content',
]

type Component = {
Expand Down
96 changes: 84 additions & 12 deletions packages/react/src/PageLayout/PageLayout.module.css
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
/* Maintain resize cursor while dragging */
/* stylelint-disable-next-line selector-no-qualifying-type */
body[data-page-layout-dragging='true'] {
cursor: col-resize;
}

/* Disable text selection while dragging */
/* stylelint-disable-next-line selector-no-qualifying-type */
body[data-page-layout-dragging='true'] * {
user-select: none;
}

.PageLayoutRoot {
/* Region Order */
--region-order-header: 0;
Expand Down Expand Up @@ -357,6 +345,12 @@ body[data-page-layout-dragging='true'] * {
flex-grow: 1;
flex-shrink: 1;

/**
* OPTIMIZATION: Isolate content area from rest of page
* Note: No 'paint' containment to allow overflow effects (tooltips, modals, etc.)
*/
contain: layout style;

&:where([data-is-hidden='true']) {
display: none;
}
Expand All @@ -383,6 +377,26 @@ body[data-page-layout-dragging='true'] * {
}
}

/**
* OPTIMIZATION: Aggressive containment during drag for ContentWrapper
* CSS handles most optimizations automatically via :has() selector
* JavaScript only handles scroll locking (can't be done in CSS)
*/
.PageLayoutContent:has(.DraggableHandle[data-dragging='true']) .ContentWrapper {
/* Add paint containment during drag - safe since user can't interact */
contain: layout style paint;

/* Disable interactions */
pointer-events: none;

/* Disable transitions to prevent expensive recalculations */
transition: none;

/* Force compositor layer for hardware acceleration */
will-change: width;
transform: translateZ(0);
}

.Content {
width: 100%;

Expand All @@ -392,6 +406,14 @@ body[data-page-layout-dragging='true'] * {
margin-left: auto;
flex-grow: 1;

/**
* OPTIMIZATION: Skip rendering off-screen content during scrolling/resizing
* This automatically helps consumers with large content by only rendering
* elements that are visible in the viewport
*/
content-visibility: auto;
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The contain-intrinsic-size value of 500px appears to be a magic number without explanation. Add a comment explaining why 500px was chosen as the intrinsic height estimate for off-screen content, as this affects how browsers estimate content size during scrolling.

Suggested change
content-visibility: auto;
content-visibility: auto;
/*
* 500px was chosen as a reasonable estimate for the typical height of page content.
* This helps browsers reserve space for off-screen content when using content-visibility: auto,
* reducing layout shifts and scroll jumps. Adjust if your average content height differs significantly.
*/

Copilot uses AI. Check for mistakes.
contain-intrinsic-size: auto 500px;

&:where([data-width='medium']) {
max-width: 768px;
}
Expand All @@ -409,6 +431,16 @@ body[data-page-layout-dragging='true'] * {
}
}

/**
* OPTIMIZATION: Freeze content layout during resize drag
* This prevents expensive recalculations of large content areas
* while keeping content visible (just frozen in place)
*/
.PageLayoutContent:has(.DraggableHandle[data-dragging='true']) .Content {
/* Full containment (without size) - isolate from layout recalculations */
contain: layout style paint;
}

.PaneWrapper {
display: flex;
width: 100%;
Expand Down Expand Up @@ -585,6 +617,15 @@ body[data-page-layout-dragging='true'] * {
/* stylelint-disable-next-line primer/spacing */
padding: var(--spacing);

/**
* OPTIMIZATION: Full containment for pane - isolates from rest of page
*/
contain: layout style paint;
/**
* OPTIMIZATION: For extremely tall content - skip rendering off-screen content
*/
content-visibility: auto;

@media screen and (min-width: 768px) {
overflow: auto;
}
Expand All @@ -598,6 +639,26 @@ body[data-page-layout-dragging='true'] * {
}
}

/**
* OPTIMIZATION: Performance enhancements for Pane during drag
* CSS handles all optimizations automatically - JavaScript only locks scroll
*/
.PaneWrapper:has(.DraggableHandle[data-dragging='true']) .Pane {
/* Full containment - isolate from layout recalculations */
contain: layout style paint;

/* Disable interactions during drag */
pointer-events: none;

/* Disable transitions during drag */
transition: none;

/* Force hardware acceleration */
will-change: width, transform;
transform: translateZ(0);
backface-visibility: hidden;
}

.PaneHorizontalDivider {
&:where([data-position='start']) {
/* stylelint-disable-next-line primer/spacing */
Expand Down Expand Up @@ -696,12 +757,22 @@ body[data-page-layout-dragging='true'] * {
padding: var(--spacing);
}

/**
* DraggableHandle - Interactive resize handle
*/
.DraggableHandle {
position: absolute;
inset: 0 -2px;
cursor: col-resize;
background-color: transparent;
transition-delay: 0.1s;

/**
* OPTIMIZATION: Prevent touch scrolling and text selection during drag
* This is done in CSS because it needs to be set before any pointer events
*/
touch-action: none;
user-select: none;
}

.DraggableHandle:hover {
Expand All @@ -710,6 +781,7 @@ body[data-page-layout-dragging='true'] * {

.DraggableHandle[data-dragging='true'] {
background-color: var(--bgColor-accent-emphasis);
cursor: col-resize;
}

.DraggableHandle[data-dragging='true']:hover {
Expand Down
Loading
Loading