perf(motion): convert layout-property transitions to transforms

Audit P1: 5 of 7 layout-property animations were transition-[width]
or transition-[left] — these trigger reflow + repaint every frame.
Convert to transform-based equivalents that run on the compositor.

Subscription.tsx — 3 progress bars + 1 toggle:
  • Device usage bar (track w-16) — width % → scaleX with a 0.0625
    floor (= 4px on 64px track) preserving the minWidth: 4px guard
    when connectedDevices > 0.
  • Traffic-purchase progress — absolute inset-0 + width % →
    transform: scaleX with origin-left, gradient stretches with the
    fill same as before.
  • Subscription period progress — same conversion.
  • Autopay toggle thumb — left: 3↔26px → translateX(0↔23px) with
    fixed left: 3px. role='switch' + aria-checked unchanged.

globals.css — .progress-fill utility class:
  • transition-property: width, background-color → transform,
    background-color. Width set to w-full + origin-left so consumers
    just set transform: scaleX(0..1). Currently has no .tsx consumers
    (grep clean) but the API stays valid for future use.

Skipped (bounded one-shot, transform alternative has tradeoffs):
  • Info.tsx + InfoPageView.tsx accordion height. Animating from 0
    to content-driven scrollHeight needs layout one way or another —
    grid-template-rows 0fr/1fr and max-height also layout-class
    properties; transform: scaleY squishes text contents. Cost is
    bounded: one animation per user click, not continuous, not on
    critical path. Separate work if priority changes.

Visual parity: scaleX renders identical geometry to width % on the
inner fill. box-shadow on the device bar (0 0 8px 40)
scales proportionally — tiny visual difference at full width, none
visible at partial widths.
This commit is contained in:
c0mrade
2026-05-26 20:27:47 +03:00
parent cef675825b
commit eb13689ae7
2 changed files with 23 additions and 11 deletions

View File

@@ -630,8 +630,10 @@ img.twemoji {
}
.progress-fill {
@apply h-full rounded-full duration-500 ease-smooth;
transition-property: width, background-color;
/* GPU-composited progress fill — consumer sets transform: scaleX(0..1)
with transform-origin: left. Avoids width-triggered reflow per frame. */
@apply h-full w-full origin-left rounded-full duration-500 ease-smooth;
transition-property: transform, background-color;
}
/* Stat card - Dark */