Skip to content
This repository was archived by the owner on Jul 19, 2019. It is now read-only.
This repository was archived by the owner on Jul 19, 2019. It is now read-only.

50x performance hit vs <canvas> #52

Open

Description

@nornagon

Perhaps I'm doing something trivially wrong, but with the below code which draws 2000 random rectangles on the canvas, react-art runs at about 5fps on my machine. The comparable code that uses the canvas API directly runs at a smooth 60fps. In fact, it takes until about 100,000 rects to bring the implementation down to 5fps.

Most (~70%) of the time seems to be spent in the ReactMultiChild.Mixin._updateChildren method:

Most of the self-time that isn't GC is in ReactElement:
developer_tools_-_http___localhost_5000_transcriptic_p17rvy7j9dzrw_runs_r17rvydszmnab_admin

Here's the code:

Test = React.createClass
  render: ->
    React.createElement 'div',
      onMouseMove: => @forceUpdate()
      onMouseDown: => @ivl = setInterval (=> @forceUpdate()), 16
      onMouseUp: => clearInterval @ivl
      React.createElement Surface,
        width: 800, height: 800
        React.createElement Group,
          y: 10, x: 10
          for [1..2000]
            React.createElement Rectangle, x: Math.random() * 800, y: Math.random() * 800, width: Math.random() * 40, height: Math.random() * 40, fill: 'red'



TestCanvas = React.createClass
  render: ->
    React.createElement 'canvas',
      width: 800 * devicePixelRatio, height: 800 * devicePixelRatio
      style: {
        width: 800
        height: 800
      }
      onMouseMove: => @paint()
      onMouseDown: => @ivl = setInterval @paint, 16
      onMouseUp: => clearInterval @ivl
  componentDidMount: ->
    @paint()

  paint: ->
    ctx = @getDOMNode().getContext '2d'
    ctx.save()
    ctx.scale(devicePixelRatio, devicePixelRatio)
    ctx.clearRect(0, 0, 800, 800)
    ctx.fillStyle = 'red'
    for [1..2000]
      ctx.fillRect Math.random() * 800, Math.random() * 800, Math.random() * 40, Math.random() * 40
    ctx.restore()

Activity

  1. demc commented on Jul 8, 2015

    @demc

    What are you using to measure your canvas frame rate?

  2. nornagon commented on Jul 8, 2015

    @nornagon
    Author

    Chrome devtools fps meter.
    On Wed, Jul 8, 2015 at 12:14 dmcmillen notifications@github.com wrote:

    What are you using to measure your canvas frame rate?

    —
    Reply to this email directly or view it on GitHub
    #52 (comment).

  3. sophiebits commented on Jul 15, 2015

    @sophiebits
    Member

    At the very least, you should be using the production (minified, NODE_ENV=production) version of React.

  4. pavlelekic commented on Oct 10, 2015

    @pavlelekic

    I'm not sure if this would completely solve your problem, but I see some things that don't look right to me. That ReactMultiChild.Mixin._updateChildren is called from ReactEventListener.dispatchEvent, that's probably because of onMouseMove: => @paint() and onMouseMove: => @forceUpdate(). Mouse move events are firing at a very high rate, what you want to do is save the last event object to a variable, and then only render component with those last mouse move values once per frame. Now I know that react is not using request animation frame by default, you may want to look into https://github.com/petehunt/react-raf-batching.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions