atom/atom — pull request #2325 by nathansobo (2014-05-21 04:08:29+00:00)
Title: For discussion: Overhead of React components for lines and line numbers

This PR is more for discussion than merging. This is a rough example of what it would look like to render the lines and line numbers using standard React components. I would love input from @petehunt or another member of the React team.

As you can see below, the overhead appears to be significant over the current manual DOM manipulation approach. The first part of the timeline is an accelerating scroll in two different versions of the editor, the first full react from this PR, the second with manual DOM manipulation from master. Note the larger amount of yellow JS time in the first timeline.

The first shot is zoomed in on a frame from this PR with React components.

![screenshot_2014-05-20_21_49_42](https://cloud.githubusercontent.com/assets/1789/3035918/47d2ed6e-e09b-11e3-83a3-c1bf3927fa22.png)

The second shot is zoomed in on a frame from master.

![screenshot_2014-05-20_21_50_21](https://cloud.githubusercontent.com/assets/1789/3035926/7d5faaee-e09b-11e3-8cfc-15c7f4ba71c5.png)

If anyone has input on how I could use React more effectively, that would be interesting. Also, could React be optimized for this use case? I would love to use the simpler, more declarative approach that the virtual DOM provides, but it has to be fast.

-----

These were generated with the following script in my `init.coffee`, run on `huge.js` (which is jQuery) in the Atom repository.

```coffee
atom.workspaceView.command 'user:test-scroll-sequence', ->
console.timeline('scroll down')
testScrolling -50, ->
testScrolling -100, ->
testScrolling -200, ->
testScrolling -400, ->
testScrolling -800, ->
testScrolling -1600, ->
console.timelineEnd('scroll down')

testScrolling = (delta, cb) ->
editorNodes = document.querySelectorAll('.editor')
editorNode = editorNodes[editorNodes.length - 1]
scrollViewNode = editorNode.querySelector('.scroll-view')
editor = atom.workspace.getActiveEditor()

scrollDown = ->
scrollViewNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -0, wheelDeltaY: delta))
editorNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -0, wheelDeltaY: delta))

stopScrolling = ->
clearInterval(interval)
cb?()

interval = setInterval(scrollDown, 10)
setTimeout(stopScrolling, 600)
```