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

React renderToString / renderToStaticMarkup blocking event loop #368

Open
dmitrif opened this issue Oct 17, 2015 · 5 comments
Open

React renderToString / renderToStaticMarkup blocking event loop #368

dmitrif opened this issue Oct 17, 2015 · 5 comments

Comments

@dmitrif
Copy link

dmitrif commented Oct 17, 2015

React renderToString & renderToStaticMarkup are blocking the event loop and therefore delaying further requests.

This is not noticeable when the # of requests is in the lower range, but problematic at larger scales. Last request to come in has to wait for all previous requests to render before being able to do the same, resulting in the 90th and 99th percentile of request response times to be abnormally high.

For example, with 1000 requests with concurrency level 1 (production mode):

ab -l -k -n 1000 -c 1 http://127.0.0.1:3000/
....
Concurrency Level:      1
Time taken for tests:   16.273 seconds
Complete requests:      1000
Failed requests:        0
Keep-Alive requests:    1000
Total transferred:      37306337 bytes
HTML transferred:       37078337 bytes
Requests per second:    61.45 [#/sec] (mean)
Time per request:       16.273 [ms] (mean)
Time per request:       16.273 [ms] (mean, across all concurrent requests)
Transfer rate:          2238.79 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    14   16   2.4     15      28
Waiting:       14   16   2.4     15      28
Total:         14   16   2.3     15      28

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     16
  75%     18
  80%     18
  90%     19
  95%     21
  98%     24
  99%     25
 100%     28 (longest request)

The variance is fairly small, with the requests being processed at approximately the same speed across the board.

Now with concurrency level 20:

> ab -l -k -n 1000 -c 20 http://127.0.0.1:3000/
Benchmarking 127.0.0.1 (be patient)
....
Concurrency Level:      20
Time taken for tests:   14.957 seconds
Complete requests:      1000
Failed requests:        0
Keep-Alive requests:    1000
Total transferred:      37298429 bytes
HTML transferred:       37070429 bytes
Requests per second:    66.86 [#/sec] (mean)
Time per request:       299.142 [ms] (mean)
Time per request:       14.957 [ms] (mean, across all concurrent requests)
Transfer rate:          2435.25 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       2
Processing:    54  297  29.5    292     358
Waiting:       54  297  29.5    292     358
Total:         56  297  29.4    292     358

Percentage of the requests served within a certain time (ms)
  50%    292
  66%    303
  75%    314
  80%    322
  90%    333
  95%    341
  98%    347
  99%    355
 100%    358 (longest request)

As you can see the variance is dramatically higher. The minimum response time is 54, meanwhile the 50th percentile is already at 292ms.

A partial solution that seems to work is to schedule data fetches on nextTick along with the final renders, giving a chance to all requests to run "concurrently".

The react team seems to be aware and mentioned that they are concentrating on server-side rendering speeds / optimizations in the next six months.

@erikras
Copy link
Owner

erikras commented Oct 17, 2015

Great data, @dmitrif, thank you.

@renholm
Copy link

renholm commented Nov 10, 2015

@dmitrif Thanks!

For future reference the issue seems to be tracked here facebook/react#1739.

@AbrahamAlcaina
Copy link

It exists a project react-dom-stream to do not block the loop.

@dmitrif
Copy link
Author

dmitrif commented Nov 11, 2015

@renholm Not sure if it fixes the same issue as the operation even in a promise would ultimately be part of the event loop, correct?

@dmitrif
Copy link
Author

dmitrif commented Nov 11, 2015

@AbrahamAlcaina Very interesting. Will investigate further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants