react-doctor/no-global-css-variable-animation
Set the variable on the nearest element instead of a parent, or use `@property` with `inherits: false` to prevent cascade. Better yet, use targeted `element.style.transform` updates
- Category: Performance
- Severity: error
- Source:
oxlint-plugin-react-doctor - Framework: global
- Enabled when: always
Validation prompt
Use this to decide whether a fired diagnostic is real or a false positive.
Confirm a CSS custom property (string literal starting with --) is set via .setProperty() inside a requestAnimationFrame or setInterval callback. Each write forces style recalculation on every descendant that inherits the variable, every frame. False positive: the element has no descendants, so cascade cost is bounded.
Fix prompt
Use this once validation confirms the diagnostic is real.
Set the variable on the nearest element instead of an ancestor, declare it with @property { inherits: false } to halt the cascade, or skip CSS variables entirely and write element.style.transform = ... directly each frame for compositor-only updates. See https://developer.mozilla.org/en-US/docs/Web/CSS/@property
Related rules
More Performance rules from the rules reference:
react-doctor/no-inline-bounce-easing: Use `cubic-bezier(0.16, 1, 0.3, 1)` (ease-out-expo) for natural deceleration — objects in the real world don't bouncereact-doctor/no-inline-prop-on-memo-component: Hoist the inline `() => ...` / `[]` / `{}` to a stable reference (useMemo, useCallback, or module scope) so the memoized child doesn't re-render every parent renderreact-doctor/no-large-animated-blur: Keep blur radius under 10px, or apply blur to a smaller element. Large blurs multiply GPU memory usage with layer sizereact-doctor/no-layout-property-animation: Use `transform: translateX()` or `scale()` instead — they run on the compositor and skip layout/paintreact-doctor/no-layout-transition-inline: Use `transform` and `opacity` for transitions — they run on the compositor thread. For height animations, use `grid-template-rows: 0fr → 1fr`