Review
Parallax hero with CSS scroll-driven animation
The winery estate landing page janks on mid-range phones when the vineyard backdrop tracks scroll. Drop the scroll listener / rAF offset loop and drive the hero parallax with CSS scroll-driven animations so the compositor owns the work.
ReactTier 1cssperformancefrontend
Click a line to flag it, pick one or more labels, then submit. If the change looks correct, approve it.
src/marketing/EstateHero.tsx+6-20
| 14 | 14 | export function EstateHero({ estate }: { estate: Estate }) { | |
| 15 | - | const [offsetY, setOffsetY] = useState(0); | |
| 16 | - | ||
| 17 | - | useEffect(() => { | |
| 18 | - | let frame = 0; | |
| 19 | - | const onScroll = () => { | |
| 20 | - | cancelAnimationFrame(frame); | |
| 21 | - | frame = requestAnimationFrame(() => setOffsetY(window.scrollY * 0.35)); | |
| 22 | - | }; | |
| 23 | - | window.addEventListener("scroll", onScroll, { passive: true }); | |
| 24 | - | return () => { | |
| 25 | - | cancelAnimationFrame(frame); | |
| 26 | - | window.removeEventListener("scroll", onScroll); | |
| 27 | - | }; | |
| 28 | - | }, []); | |
| 29 | 15 | ||
| 30 | 16 | return ( | |
| 31 | 17 | <section className="estate-hero relative h-[70vh] overflow-hidden"> | |
| 32 | - | <img | |
| 33 | - | src={estate.coverUrl} | |
| 34 | - | alt="" | |
| 35 | - | className="absolute inset-0 h-[120%] w-full object-cover" | |
| 36 | - | style={{ transform: `translate3d(0, ${offsetY}px, 0)` }} | |
| 37 | - | /> | |
| 18 | + | <img | |
| 19 | + | src={estate.coverUrl} | |
| 20 | + | alt="" | |
| 21 | + | className="estate-hero__parallax absolute inset-0 h-[120%] w-full object-cover" | |
| 22 | + | /* animation-timeline: scroll(); drives translateY without JS */ | |
| 23 | + | /> | |
| 38 | 24 | <div className="relative z-10 flex h-full flex-col justify-end p-8 text-white"> | |
| 39 | 25 | <h1 className="font-serif text-4xl">{estate.name}</h1> | |
| 40 | 26 | <p className="mt-2 max-w-lg text-white/80">{estate.tagline}</p> | |
| 41 | 27 | </div> | |
| 42 | 28 | </section> | |
| 43 | 29 | ); | |
| 44 | 30 | } |