Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to React #729

Merged
merged 12 commits into from
Jul 23, 2016
Merged

Switch to React #729

merged 12 commits into from
Jul 23, 2016

Conversation

dcposch
Copy link
Contributor

@dcposch dcposch commented Jul 20, 2016

The goal is to make the app faster and smoother. As a bonus, React is more standard and more actively maintained than hyperx/virtual-dom/main-loop.

See #725 for motivation

@feross

@dcposch
Copy link
Contributor Author

dcposch commented Jul 20, 2016

Work left to do

  • Fix all React warnings
  • Test speed improvement
  • Fix the packaging scripts

@dcposch
Copy link
Contributor Author

dcposch commented Jul 20, 2016

We should also use React in a more idiomatic way. I ported it with minimum changes, but later on we should convert function calls that return a vdom like {Header(..)} into their own React components like <Header ... />

@dcposch dcposch force-pushed the dc/perf branch 2 times, most recently from b7a60e3 to d2e3cfd Compare July 21, 2016 05:41
@dcposch
Copy link
Contributor Author

dcposch commented Jul 21, 2016

Speed test

  • Load this torrent and expand it
  • Open the dev tools, go to Timeline view, start recording
  • Scroll for a few seconds, then stop recording

The timeline view shows FPS and breaks down where time is being spent.

hyperx

Can't really scroll. See #725
Computing the vdom: ~500ms
Applying the vdom to the actual dom: didn't measure

React

With React in production mode (extra checks and warnings disabled with NODE_ENV=production, which is what our users see):
Computing the vdom: ~10ms
Applying the vdom to the actual dom: ~60ms

This is better, but unfortunately the scrolling is still choppy. First, 70ms is a lot longer than 16ms, so you are freezing for a few frames (compared to 60fps) every time you call update(). Second, even when the DOM is not updating at all, Chrome can't scroll it smoothly.

Below, the orange parts correspond to time spent in JS (our code and React). The purple parts are time spent in Chrome rendering frames of scrolling animation while the DOM isn't changing.

screen shot 2016-07-20 at 10 59 35 pm

In short it's better now, but still not smooth. IMO this PR is a good first step. Next we'll have to make the DOM more lightweight (eg by capping the number of file rows we show).

@dcposch
Copy link
Contributor Author

dcposch commented Jul 23, 2016

The dom is just SLOW

I saved the torrent list view as static HTML:

screen shot 2016-07-22 at 5 21 44 pm

A few stats:

  • torrent-details.html is only 97KB
  • There are only 351 rows in the table
  • The table layout is really easy to compute
    • table-layout: fixed in the CSS, so no autosizing columns
    • The rows have a fixed pixel height
    • The side columns have fixed pixel width. The middle column takes the remaining width

And this is plain HTML + CSS, no Javascript of any kind.

Anyway despite that, when mousing over the list, the :hover state is very choppy.

As you can see below it runs at about 10FPS.

screen shot 2016-07-22 at 5 34 07 pm

@dcposch dcposch closed this Jul 23, 2016
@dcposch dcposch reopened this Jul 23, 2016
Turns out this is huge. For some inexplicable reason, it improves hover and scroll in the torrent detail view, for a torrent with 350 files, from ~10FPS to ~60FPS.
@feross
Copy link
Member

feross commented Jul 23, 2016

@dcposch Here's an idea: remove the background image. It's hugely stretched. I bet that's causing this.

@@ -129,8 +129,6 @@ module.exports = class TorrentController {
// files which are completed after a video starts to play to be added
// dynamically to the list of subtitles.
// checkForSubtitles()

dispatch('update')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was causing double update()s.

@@ -14,9 +15,11 @@
height: 140px;
}
</style>
<script>
require('../build/renderer/webtorrent.js')
Copy link
Member

@feross feross Jul 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question: why not <script async ...>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing that breaks require(). If we want <script ...> to work, we either have to:

  • Write ugly things like require('../build/renderer/<etc>') in the actual source files
  • Move main.html to be next to main.js

Doing it this way lets us separate src/ for JS sources only and static/ for HTML, CSS, etc

@feross
Copy link
Member

feross commented Jul 23, 2016

Hey @dcposch, this is nice work! 👍 👍 👍

Never used React before, but curious to see how this goes. It looks pretty nice so far. I left lots of comments and questions inline.

Once comments are addressed, let's merge this! I think we shouldn't release for a few days after this is merged since I wasn't able to compare line-by-line for some of the files. Some of the file diffs just show every line removed, then every line added. :( So let's wait a few days for any bugs to get shaken out.

Maybe React isn't so bad...

@feross feross added the perf label Jul 23, 2016
@dcposch
Copy link
Contributor Author

dcposch commented Jul 23, 2016

@feross I tried removing the background image, but that wasn't the cause of the slowness.

@feross
Copy link
Member

feross commented Jul 23, 2016

👍

@dcposch
Copy link
Contributor Author

dcposch commented Jul 23, 2016

Startup time

Checking the logs for the init timer.

Measured on a 2016 12" Macbook running Mac OS El Capitan.

Before (18aadf9)

main process: 850ms
renderer: 250ms

After (734b073)

main process: 830ms
renderer: 330ms

@dcposch
Copy link
Contributor Author

dcposch commented Jul 23, 2016

And scrolling thru the 350 files in Adventures of Huckleberry Finn is fast now!

@feross
Copy link
Member

feross commented Jul 23, 2016

👍 👍 👍

Add window.client = the WebTorrent client
@dcposch dcposch merged commit d21396c into master Jul 23, 2016
@feross feross deleted the dc/perf branch July 25, 2016 23:43
@lock lock bot locked as resolved and limited conversation to collaborators Jan 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants