React-spring: [Performance] Can't animate larger amounts of children in Trail animation

Created on 24 May 2018  路  5Comments  路  Source: pmndrs/react-spring

I found out I can't animate more than a certain amount of items using Trail before my browser just straight up freezes. I think the limit is around 15, but it might also have to do with the type of transition. The target in my use case is quite high, around 25.

This can be reproduced using your codepen sandbox by adding more items to the state:
https://codesandbox.io/embed/vvmv6x01l5

note: I used native rendering, but could reproduce with and without native rendering.

Most helpful comment

Should be fixed. If you still need a duration based Trail, it is easy to create your own primitives:

class DurationTrail extends React.Component {
  getValues = () => this.ref.getValues()
  render() {
    const { children, delay = 0, ms = 50, keys, onRest, ...props } = this.props
    return children.map((child, i) => {
      return (
        <Spring
          ref={ref => i === 0 && (this.ref = ref)}
          key={keys[i]}
          {...props}
          delay={delay + (i * ms)}
          onRest={i === children.length - 1 ? onRest : null}
          children={child}
        />
      )
    })
  }
}

<DurationTrail native keys={list.map(i => i.key)} from={...} to={...}>
  {list.map(item => style => <animated.div style={style} ... />)}
</DurationTrail>

It won't be as fluid since duration kind of prevents spring physics, but in most situations it won't matter, and this will be as fast as it gets.

All 5 comments

I noticed the same, hadn鈥檛 looked into it yet, thought possibly I was doing something wrong.

Also noticed, and thought it was my fault!

Strange, there seems to be something that's blocking it, then after a while it starts animating. When i find time i'll investigate.

It's something in animated, the flush function is called thousands of times. It should only be called once. Something's clearing the cached animation-tree while it's animating.

Should be fixed. If you still need a duration based Trail, it is easy to create your own primitives:

class DurationTrail extends React.Component {
  getValues = () => this.ref.getValues()
  render() {
    const { children, delay = 0, ms = 50, keys, onRest, ...props } = this.props
    return children.map((child, i) => {
      return (
        <Spring
          ref={ref => i === 0 && (this.ref = ref)}
          key={keys[i]}
          {...props}
          delay={delay + (i * ms)}
          onRest={i === children.length - 1 ? onRest : null}
          children={child}
        />
      )
    })
  }
}

<DurationTrail native keys={list.map(i => i.key)} from={...} to={...}>
  {list.map(item => style => <animated.div style={style} ... />)}
</DurationTrail>

It won't be as fluid since duration kind of prevents spring physics, but in most situations it won't matter, and this will be as fast as it gets.

Was this page helpful?
0 / 5 - 0 ratings