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

Support for async rendering #19030

Open
SebastianSchenk opened this Issue Sep 4, 2017 · 21 comments

Comments

Projects
None yet
@SebastianSchenk
Copy link

SebastianSchenk commented Sep 4, 2017

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

The new version of React (16.x) will introduce a core feature called async rendering.
(https://edgecoders.com/react-16-features-and-fiber-explanation-e779544bb1b7)

This allows the framework to render a lot of things at the same time without blocking the main thread.

Thanks to this feature the ui feels much more fluid. You can see it in this demo where stacked rendering (synchronous) and fibre (asynchronous) rendering are compared.
https://claudiopro.github.io/react-fiber-vs-stack-demo/

I was wondering, is this something that can also be implemented in angular? If so, are there any plans for a similar feature?

Current behavior

Component rendering is happening synchronous --> blocks the main thread.

Expected behavior

Component rendering is happening asynchronous --> doesn't block the main thread.

@mlc-mlapis

This comment has been minimized.

Copy link

mlc-mlapis commented Sep 4, 2017

React Async Rendering
The focus of the initial 16.0 release is on compatibility for existing applications. Async rendering will not be an option initially, but in later 16.x releases, it will be included as an opt-in feature.

Web Worker solution for async rendering is still a big question. There are no serious data to compare the final effects. It'll be probably highly dependent on exact cases.

@SebastianSchenk

This comment has been minimized.

Copy link
Author

SebastianSchenk commented Sep 4, 2017

@mlc-mlapis yeah I know it is not included yet, but it will be.

You can run whatever code you like inside the worker thread, with some exceptions. For example, you can't directly manipulate the DOM from inside a worker, or use some default methods and properties of the window object. But you can use a large number of items available under window, including WebSockets, and data storage mechanisms like IndexedDB and the Firefox OS-only Data Store API. See Functions and classes available to workers for more details.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

I don't think web workers will effect render performance in the same way, since you cannot access the DOM there. I think the idea behind web workers is to perform heavy computation on a seperat thread.

@mlc-mlapis

This comment has been minimized.

Copy link

mlc-mlapis commented Sep 4, 2017

@SebastianSchenk ... yes, it's true ... to perform heavy computation on a seperat thread. These type of tasks are available even today for any app ... including Angular.

There are Angular modules:

"@angular/platform-webworker": "4.3.6",
"@angular/platform-webworker-dynamic": "4.3.6"

You can also look at:
https://blog.angularindepth.com/angular-with-web-workers-step-by-step-dc11d5872135
https://github.com/Owain94/angular-webworker

@gund

This comment has been minimized.

Copy link

gund commented Sep 28, 2017

As far as I understand React Fiber split their update/render process into 2 different phases:

  • reconciliation (computing/diffing new virtual DOM)
  • commit (actual rendering to the DOM)

In React <=15 this process was done in single pass (as a change was found - this update will be reflected in the DOM) but now they can execute this phases differently: reconciliation can be done asynchronously (with interruptions for main thread to be responsive) but commit still in one sync pass to keep UI consistent.

The same concept can be mapped to Angular:

  • reconciliation is basically a change detection pass which can probably be done with interruptions
  • commit is the actual calls to the renderer and should be done in one pass

So async rendering is really about splitting change detection into chunks and scheduling it right but still rendering in one sync pass to reduce UI artifacts.

Here's really well explained how they approach the problem: https://www.youtube.com/watch?v=ZCuYPiUIONs

@gund

This comment has been minimized.

Copy link

gund commented Sep 29, 2017

Out of curiosity I've ported Fiber vs Stack react demo to Angular here.
I thought that app in webworker will lead to significant performance difference but actually animations still were junky because worker thread was unable to keep up with 60 fps.
However main thread clearly was not blocked.

@mlc-mlapis

This comment has been minimized.

Copy link

mlc-mlapis commented Sep 29, 2017

@gund

This comment has been minimized.

Copy link

gund commented Sep 29, 2017

@mlc-mlapis thanks for pointing out, just base tag problem.
Fixed now =)

@Toxicable

This comment has been minimized.

Copy link
Contributor

Toxicable commented Sep 29, 2017

@gund interesting, thanks for the demos.
just to add to it, if you move your viewport to the size where you demo makes a scroll bar you can tell that the work is being done on a background thread by being able to scroll while it's moving still, unlike the sync demo.

@gund

This comment has been minimized.

Copy link

gund commented Sep 30, 2017

@Toxicable yeah the fact that main thread was not blocked is really good, but if you were doing animations from the worker thread and it was blocked then still visually user might have a perception of a bad performance.
Clearly async rendering is about smart scheduling and prioritizing operations to DOM...

@Toxicable

This comment has been minimized.

Copy link
Contributor

Toxicable commented Sep 30, 2017

As far as I understand it, while running your app inside a Web Worker would be the best performance possible the bus between Worker and Main thread is currently too slow to get reasonable performance boosts from using it

@mlc-mlapis

This comment has been minimized.

Copy link

mlc-mlapis commented Sep 30, 2017

@Toxicable ... yeap, the same observation as @ghetolay observed some time ago ... the bus is the limitation. So cases where Web Worker threads are optimal to use are those ones where a lot of processing is required inside Web Worker thread with less frequencies of communication back to the main thread.

It would be interesting to know more details what is the source of such bus limitation when the bus interface works fully in local memory.

@gund

This comment has been minimized.

Copy link

gund commented Sep 30, 2017

I really do not think it's about bus throughput.
It looks like the worker thread simply unable to compute fast enough to push animation updates to UI thread.
If you will remove slow code it probably will result in 60 fps animation in worker mode same as in single thread mode.

@mlc-mlapis

This comment has been minimized.

Copy link

mlc-mlapis commented Sep 30, 2017

@gund ... hmm, as I remember the best performance is possible to get with stringifying of everything because the transfer of strings is 2-3x faster then objects.

Also for 60 frames per second it is necessary that no JS runs longer then 16 ms ... as https://hacks.mozilla.org/2015/07/how-fast-are-web-workers

@gund

This comment has been minimized.

Copy link

gund commented Sep 30, 2017

I just tried locally webworker version but without heavy load on worker thread and as expected I got 60 fps silky-smooth animations on UI.
So there is really nothing to do with webworkers - it's purely scheduling and prioritization problem...

BTW: @mlc-mlapis if you really want to hit 60 fps you should not take more than 10ms on the thread because browser also has to take some time to do it's job =)

@aretheregods

This comment has been minimized.

Copy link

aretheregods commented Mar 6, 2018

@SebastianSchenk I just wanted to correct the statement that

The new version of React (16.x) will introduce a core feature called async rendering.

It doesn't include async rendering at the moment, and it's unclear when it will. Right now, the React team says later this year. But, as it stands React and Angular are about equally fast (with Angular being a little faster) according to this benchmark

@shyamal890

This comment has been minimized.

Copy link

shyamal890 commented May 22, 2018

It seems reconciliation should already be available in Angular not sure if any thing changed in last 8 months since the issue was created.

@trotyl trotyl referenced this issue Jun 1, 2018

Closed

Angular challenge: can you do it? #24240

1 of 7 tasks complete
@hiepxanh

This comment has been minimized.

Copy link

hiepxanh commented Jun 7, 2018

I see that stencil with demo is can do that stencil by ionic demo website: smooth . I tried with service-worker but no luck.

github repository
ng6 demo website: nope
ng4 demo website: nope!
react demo website: smooth

@splincode

This comment has been minimized.

Copy link
Contributor

splincode commented Aug 13, 2018

@trotyl @Toxicable @IgorMinar @mhevery I just added requestAnimationFrame + requestIdleCallback and received 60fps

image

Angular 6:
https://angular6-fiber-next.stackblitz.io/

React Fiber:
https://claudiopro.github.io/react-fiber-vs-stack-demo/fiber.html

@hiepxanh

This comment has been minimized.

Copy link

hiepxanh commented Aug 13, 2018

wow, that amazing, thank you. how can you do that?

@hiepxanh

This comment has been minimized.

Copy link

hiepxanh commented Aug 13, 2018

thank for that link sir. that good

@Ploppy3

This comment has been minimized.

Copy link

Ploppy3 commented Jan 1, 2019

@splincode Even though the perf improvement is quite noticeable, the Angular app still stutters on every change detection cycle, could this be improved or is Angular simply slower? I'm even more concerned since I noticed that Angular Ivy is slower in its current state than the latest stable version of Angular.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.