react-spring and framer-motion laggy on firefox

Viewed 2506

I have problem with two animation libraries(react-spring, framer-motion). I was trying to make simple animation in moment when component is first time visible. (it's simplify version)

<motion.div initial={{x: -25, opacity: 0}} animate={{x: 0, opacity: 1}} transition={{duration: 2.5}} className="App-logo">NAME</motion.div>

Github project

It looks very smooth on Chrome, Brave, Edge, but on Firefox it looks laggy in the end of animation. This example is based on framer-motion but in react-spring it looks the same. When transition-duration is shorter and translateX longer it looks better but still it's not smooth animation(and it's not solution for this problem to change properties which works on other browsers). Firefox(76.0.1)(OS Win10).

I tried to do the same animation using clear css and it looks smooth on each browser. I was searching for solutions to my problem but i didn't find any particural answears.

2 Answers

I think it is the difference int the rendering engine of Firefox and Chrome. Firefox just position the div pixel by pixel without subpixel rendering. If you add a slight rotation to the div it makes FF engine to skip optimization.

<motion.div initial={{x: -25, opacity: 0, rotation: 0.02}} animate={{x: 0, opacity: 1, rotation: 0.02}} transition={{duration: 2.5}} className="App-logo">NAME</motion.div>

Update: Based on your your git repo I add an example. If I add rotation for the first two line, the animation is noticeably smoother in Firefox than with the last line.

https://codesandbox.io/s/happy-cannon-tew1f

enter image description here

I was getting laggy animations on chrome and tried something which gave me better performance than before. The animations are much smooth. You can try the same on Firefox and let me know if it worked

In Framer motion don't declare animations inside JSX directly but use variants.

change this

 <motion.div
    animate={{scale:1,opacity:1}}
    exit={{x:200,scale:2,opacity:0}}
    transition={{type:"spring",duration:1}}
    >

      <Outlet />
    </motion.div>

to this

 <motion.div
    variants={variants}
    initial="initial"
    animate="animate"
    exit="exit"
    transition="transition"
    >

      <Outlet />
    </motion.div>

variant object

 const variants = {
    initial  : {scale:0,opacity:0},
    animate : {scale:1,opacity:1},
    exit : {x:200,scale:0,opacity:0},
    transition : {type:"spring",duration:1.5}
  }
Related