react-native-community / discussions-and-proposals

Discussions and proposals related to the main React Native project
https://reactnative.dev
1.69k stars 129 forks source link

React Native Fabric (UI-Layer Re-architecture) #4

Closed kelset closed 2 years ago

kelset commented 6 years ago

Intro

With this issue I'd like to try and create a "one stop" for all the information available around the future re-architecture of the UI-Layer of React Native, codenamed "Fabric".

Terminology

TL;DR

From @axe-fb's blogpost, here's a temporary description of Fabric (please consider that this is not yet finalized, it may change in the future)

In the current architecture, all UI operations (like creating native views, managing children, etc). are handled by a native module called UIManagerModule. The React Reconciller sends UI commands over the bridge, which are eventually handled by this module and delegated to UIImplementation. This in turn creates shadow nodes that represent the layout tree and are passed to Yoga to determine the relative co-ordinates based on the Flex box styles that are passed in from JS. In the new system, the UI operations are directly exposed to JavaScript as functions using the JSI interface described above. The new UI manager can then create ComponentDescriptors and the Shadow Nodes for specific view types (like Text, View or Images), and then communicate with Java/ObjC to draw platform specific UI.

Available Materials

It was first announced in the "State of React Native 2018" blogpost by @sophiebits.

In July, @hramos linked a broadcast of a tech talk that happened in FB, which covered the ongoing work on the new React Native architecture codenamed "Fabric": facebook.com/hramos/videos/10101317533036249 (go to 8:18 for the presentation start - audio is a bit bad)

Further down the line, it was presented at ChainReact Conf 2018 by @axe-fb in the talk "The State of React Native".

At ReactConf 2018 @axe-fb did a talk about React Native's New Architecture, which also explains the 3 concepts above: JSI, Fabric, TurboModule.

On twitter, @shergin shared a presentation about View Flattening -> https://twitter.com/shergin/status/1058393187079704576?s=09

On twitter, @kmagiera shown a early stage implementation of Fabric working on the RNTester app -> https://twitter.com/kzzzf/status/1064891715457294337

IN Q1 2019, @kelset published a high-level/beginner friendly blogpost about it: https://formidable.com/blog/2019/fabric-turbomodules-part-3/ and did a talk about the whole rearchitecture in April 2019 at React Edinburgh.

@kelset also did a more in-depth talk at React Advanced London in Oct 2019: youtube recording & slides.

As of early Jan 2022, a first version of the docs about Fabric are on the main reactnative.dev website.

SWM published a blogpost on how they added Fabric to one of their libraries: https://blog.swmansion.com/introducing-fabric-to-react-native-screens-fd17bf18858e

Q&A

This is also a place for questions related to this effort and its direction.

axe-fb commented 6 years ago

Kevin's talk about Fabric internals

React Wednesday (July 25 2018)

Recording - https://www.facebook.com/hramos/videos/10101317533036249/

Video - https://www.slideshare.net/axemclion/react-native-fabric-review20180725

shergin commented 6 years ago

We can start a Q&A here where anyone involved can share knowledge and ideas. 😄

I see Fabric as an effort aimed to modernize the rendering layer of React Native. Fabric relies on some new strategies, such as:

Fabric is all about modern, easy-to-interop and performant UI.

aleclarson commented 6 years ago

This sounds really cool. :)

  1. What's the timeline for Fabric's first stable release? Is there an issue tracking the progress of development? Will there be an in-depth blog post on the internals?

    edit: I see the overview stream covers the timeline and internal concepts, but a text version would be great, too! Also, could you improve the audio quality of streams like this one by using an external microphone in the future?

  2. What does Fabric mean for developers of native modules?

  3. What problems are solved by shared memory ownership between JS and native?

  4. How does the "JSI" differ from the React Native bridge?

  5. Can you provide more details on the removal of ViewManager modules?

  6. Will the reconciler eventually be in C++?

Thanks!

shergin commented 6 years ago

@aleclarson Thank you for your question!

What's the timeline for Fabric's first stable release?

We don't have any public deadline or timeline. It's also hard to define what stable actually means for Facebook and for external users. We have quite ambitious (but realistic) plan to enable Fabric for some of the most popular RN screens in the main app. To me, the most important mark will be when we enable Fabric for all screens in all Facebook apps. It's unclear when we will hit this point, but I am pretty optimistic about that.

What does Fabric mean for developers of native modules?

Fabric doesn't affect native modules API directly (this is a separate effort), except special kind of NativeModules called ViewManagers. Fabric does not use this approach anymore, any component-specific View Managers have to be rewritten. See also below.

What problems are solved by shared memory ownership between JS and native?

Technically, this problem does not exist in the current architecture, because the shadow tree is not shared between JS and native, each side maintains own copy of the same tree. In Fabric, we have to be able to support multiple versions of (partially) immutable shadow trees, which can be created by both sides. To make this performant we have to "share ownership" of every node in those trees. So, if some particular node is not needed by both sides, it can be automatically deallocated; there is no need to maintain hash tables and send the information between worlds. JSI makes it possible exposing API that allows to call finalizes when GC collects objects.

How does the "JSI" differ from the React Native bridge?

They are similar but... totally different. They both connect JS machine with the native world.

Bridge is part of React Native. Bridge includes:

JSI is not a part of React Native, it's a unified lightweight general purpose API for (theoretically) any JavaScript virtual machine. Now there is only one implementation of that - for JavaScriptCore VM. JSI has/allows:

Can you provide more details on the removal of ViewManager modules?

In the current architecture, ViewModules almost always contain only props mapping; in Fabric this information is described as *Prop classes in C++. So, there is no need for ViewManager.

Will the reconciler eventually be in C++?

Probably. Probably not. We are thinking that something like this might be valuable and feasible in a couple of years. But, personally, I think if we are thinking about this now, we can figure out something even smarter than that. :)

kay-is commented 6 years ago

Thanks for the Q&A 😃

Will the JNI work like NativeScript does it?

I read they don't need bridges written in ObjC/Java.

shergin commented 6 years ago

@kay-is

Will the JNI work like NativeScript does it?

Do you mean JSI? I don't know how NativeScript works, so I cannot say.

kay-is commented 6 years ago

Yes, JSI, sorry.

AFAIK NativeScript exposes all native APIs in JS, so you don't need to write native code to interact with them.

axe-fb commented 6 years ago

@kay-is It is similar, but there are differences. Unlike NativeScript, we would not have a binary file that registers ALL methods on the outset. It is more like HostObjects, which can have getters/setters.

AlicanC commented 6 years ago

What side effects can we expect? Decreased build times? Decreased binary sizes?

How much of Java/ObjC code will become C++ in the end?

aljs commented 6 years ago
  1. Can you share any benchmark results? I know, it's still a WIP - but it's interesting how Fabric compares to an old realisation in terms of performance.

  2. Does this affect native Obj-C modules that aren't running on the main thread?

shergin commented 6 years ago

@AlicanC

What side effects can we expect? Decreased build times? Decreased binary sizes?

Probably, but that's not our goal. The main goal is to make the code more modern, flexible and maintainable.

How much of Java/ObjC code will become C++ in the end?

The goal is to have as small amount of platform-specific code as possible. It's hard to estimate exact amount though.

@aljs

Can you share any benchmark results? I know, it's still a WIP - but it's interesting how Fabric compares to an old realisation in terms of performance.

At this point, we don't have numbers in which we are confident enough to share. I expect to have them relatively soon though.

Does this affect native Obj-C modules that aren't running on the main thread?

(At least on iOS) All native modules which are view managers should be rewritten/adopted to Fabric, eventing else is covered by separated effort called TurboModules.

msand commented 6 years ago
  1. How will the removal of ViewManagers affect Animated and useNativeDriver?
  2. What differences are there between iOS and Android? (previous message suggests only iOS needs rewriting of view managers) Seems the removal might simplify native animation of e.g. react-native-svg. I've had to introduce property setters in the ViewManagers and Views/ViewGroups (just to contain a reference to the shadow node, in order to be able to set the properties) in addition to the shadow nodes, for all Svg elements on Android, to allow animation using the native driver. https://github.com/react-native-community/react-native-svg/pull/757/files#diff-4514e2800c86c3d034626a608dce25b2 https://github.com/facebook/react-native/pull/18187 https://github.com/react-native-community/react-native-svg/pull/757
  3. Will there be improved support for writing native modules in C++?
axe-fb commented 6 years ago

@msand For native modules (3) - note that you can already write native modules in C++. We are also working on a parallel proposal for a new architecture for native modules - https://github.com/react-native-community/discussions-and-proposals/pull/11

msand commented 6 years ago

@axe-fb Do you have any good examples? I've seen expo-gl and just now found https://github.com/sulewicz/djinni-react-native https://github.com/sulewicz/djinni-react-native/tree/master/example-react-native/ExampleProject which seems to simplify things.

msand commented 6 years ago

I'm thinking for react-native-svg the text layout algorithm from the SVG 2.0 spec might make sense to attempt implementing in c++ instead of both obj-c and java. Would be easier to maintain a single implementation.

shergin commented 6 years ago

@msand

How will the removal of ViewManagers affect Animated and useNativeDriver?

Native Animation Driver has to be rewritten, we plan to invest in it this year. Classic Animated implementation will work out of the box because it relies on setNativeProps which will fully support by Fabric soon. This is true for iOS and Android implementations.

I'm thinking for react-native-svg the text layout algorithm from the SVG 2.0 spec might make sense to attempt implementing in c++ instead of both obj-c and java. Would be easier to maintain a single implementation.

Yes, totally. I think the all non-drawing code should be unified and rewritten in C++. We plan to do this for ART soon.

sibelius commented 6 years ago

I've made an overview talk of how React Native bridge architecture works

I've made a talk that presents the current React Native Bridge architecture, explaining its characteristics, how it works and its drawbacks. I've also talked about how the new future bridge architecture will look like

https://speakerdeck.com/sibelius/react-native-bridges-architectures

I think this could be a good intro for the bridge topic

aljs commented 6 years ago

Are some parts of it already in use without a flag? (on master branch) Get a crash related to custom view manager on [self.subviews objectAtIndex:]. Only on iOS 9-10, which is weird.

mattgperry commented 6 years ago

@shergin I’m currently trying to implement the FLIP animation technique in React Native.

If you haven’t seen this in browsers, the short version: When the layout of a component changes, we can invert its positional delta via a transform, and then animate it into its new position by animating x and y back to 0

To do this seamlessly, without seeing the component in its new position for a frame, we need to guarantee onLayout is fired before the new position is drawn to the screen.

The docs say “the new layout may not yet be reflected on the screen at the time the event is received”, and indeed now and then there is a perceivable “snap”. Will Fabric allow us to guarantee execution of onLayout before the layout is reflected on the screen or am I barking up the wrong tree?

Thanks in advance for your input

fkgozali commented 6 years ago

Will Fabric allow us to guarantee execution of onLayout before the layout is reflected on the screen or am I barking up the wrong tree?

A few things:

Hope that helps.

kyashrathore commented 6 years ago

will this re architecture of react native yield performance as good as flutter or flutter's performance is just hyped about?I have learned react recently and I love it ,will it prove to be a good decision to learn react-native for native mobile apps or in core of your heart you feel flutter is better?

shergin commented 6 years ago

@contactyash

  1. Fabric is designed to be (incredibly) responsive and interopable.
  2. Real performance Flutter vs. Fabric is incomparable unless we have big production apps written in both of them.
  3. All apps that I have seen in Flutter don't demonstrate impressive performance unfortunately (totally bias opinion).
joonhocho commented 6 years ago

The two main reasons that I stopped using on React Native were Navigation and ListView. For navigation, I think I've tried 5 different libraries including React Navigation and all felt sluggish. I think wix/react-native-navigation v2 can finally address the problem. I have my hopes up. For ListView, I've tried every library and every optimization solution out there and it all failed miserably for large lists with pictures and few dynamic components. In the end, I had to bridge native tableview and native cells in order to make it useable. App startup kept getting slower as app grew large as well. I really hope this re-architecture finally fixes these issues. ListView and Navigation are the most commonly used components in any apps, and they are still the main problems after 5 years for React Native. With sync communication between native and js, will it be possible to use native native tableview with cells being rendered in js?

shergin commented 6 years ago

@joonhocho Yes, Fabric is a foundation that meant to help improve things including navigation (sync external interop) and lists (better/sync measuring API, build-in view recycling and flattening). Fabric itself will not solve that, but it will enable actual solutions.

joonhocho commented 6 years ago

@shergin I am wondering, in new react native architecture, whether even the rendering can be synchronized. I believe IOS UITableView requires synchronized rendering of cells. That means React should render and return native cell view to the tableview in synchronized way. Will this kind of behavior supported by the new architecture or rendering will be always asynchronous?

shergin commented 6 years ago

Yes, Fabric will support synchronous rendering (state change). However, relying on UITableView it's not the only way to implement smooth and fluid lists, the actual approach and API might be different.

tayfunyugruk commented 6 years ago

@shergin when Fabric reaches beta level will we be able to use both JSI and Bridge at the same time ? I am trying to learn if we will need to wait until every component is ported to new architecture or they will be able to live together until Fabric takes over ? Thanks.

Also i think/hope Fabric will help resolving many core problems, thanks for starting this re-architecture team. My best wishes for React Native.

gengjiawen commented 6 years ago

I have some questions:

fkgozali commented 6 years ago

when Fabric reaches beta level will we be able to use both JSI and Bridge at the same time ? I am trying to learn if we will need to wait until every component is ported to new architecture or they will be able to live together until Fabric takes over ?

See @shergin's comment regarding timeline: https://github.com/react-native-community/discussions-and-proposals/issues/4#issuecomment-415999104

At the moment, the system allows both Fabric compatible components and the existing view manager-based components. At some point in the future though, all components need to be Fabric-compatible. We'll share more details around the plan in later time until the core of Fabric is more complete and stable.

Will fabric comes with big list optimization by default. If not, is this on some schedule.

@shergin touched this in his previous comments:

Will fabric bring new api like SyncStorage

Fabric is just about the UI layer of ReactNative. SyncStorage seems like something that could benefit from synchronous calls to native (whether or not JSI will be used). If you want to call native synchronously, it is already possible today: https://github.com/react-native-community/discussions-and-proposals/pull/11#discussion_r210370835. We're working on an effort to improve calls to native from JS as a whole though, separate from Fabric: https://github.com/react-native-community/discussions-and-proposals/issues/40

kelset commented 6 years ago

(updated the first comment with a link to Ram's talk at ReactConf)

rstims commented 6 years ago

Is the JSI project going to be open-sourced? If so, where can we view it?

fkgozali commented 6 years ago

JSI already landed on master. See the series of commits ending with https://github.com/facebook/react-native/commit/8427f64e06456f171f9df0316c6ca40613de7a20

Raat-Jaaga-Taara commented 6 years ago

The biggest concerns I have seen in RN today are:

I see other speakers including @axe-fb Ram talking about the Fabric to help enable navigation and large lists. How will the other three work in Fabric?

kelset commented 6 years ago

(updated first comment with Shergin's tweet about View Flattening)

fkgozali commented 6 years ago

large list & Navigation

Please see @shergin's comment here https://github.com/react-native-community/discussions-and-proposals/issues/4#issuecomment-428023114 - Fabric enables solutions for these problems, but the Fabric project doesn't include the solutions.

Android overflow in hybrid apps, lazy bundle loading to improve boot time, Debugging code in app runtime

These are not related to Fabric project.

Raat-Jaaga-Taara commented 6 years ago

Android overflow: see facebook/react-native@b81c8b5 I had seen this commit but will this enable me to render something outside the bounds of the reactroot view?

terrysahaidak commented 6 years ago

I'm really excited about Fabric. Thanks for the core team making that happened.

But still, does the Fabric fixes the most annoying part of React Native – layout animation, i.e. width/height animations which cannot be started using useNativeDriver option. I didn't find any information about that.

mobilehackersio commented 6 years ago

can't wait for Fabric 🚀

shergin commented 6 years ago

@terrysahaidak The role and concrete implementation of the native driver in Fabric is still not clear. We hope that Fabric’s sync nature can enable new approaches to solve those problems more efficiently.

tomduncalf commented 6 years ago

Does this mean C++ native modules will become a first class, documented citizen of the RN universe? That would be awesome, I’m doing a lot of work in this area and most of it had to be figured out by reverse engineering/trial and error :) Sounds exciting anyway, thanks for the information!

msand commented 6 years ago

I'm thinking that ideally, with the new fabric rewrite of react-native, we would generate a native svg rendering library interface (c++, js, ts, flow) from the WebIDL spec of svg 2.0 to cover the entire api (using something like https://github.com/Microsoft/TSJS-lib-generator and https://github.com/motiz88/webidl-to-flow), use rust implementations for processing (https://github.com/RazrFalcon/resvg) and rasterizing it (https://github.com/pcwalton/pathfinder or https://github.com/nical/lyon).

Then make a small wrapper with java + objective-c glue to attach to the view hierarchy and hit testing / gesture responder / event system, such that it can be used from react-native, (and perhaps c#, kotlin, dart, python, ruby, julia, r etc. to get more platforms) as well as any other native environment, with a single cross-platform, efficient, memory and thread safe implementation. Having the WebIDL specified api would allow much of the existing js which runs against svg implementations in e.g. browsers to work almost straight away. And, give a nice escape hatch around the async bridge and vdom diffing.

I think it would make sense to name this something else than react-native-svg, that could still live on with its java and obj-c implementations at least as a baseline for perf benchmarks, as this is more cross-platform. This would be more of an embeddable svg engine, mirroring the full svg related subset of js apis available in browsers, which can be embedded when you need svg rendering and want to interact with it from e.g. a javascript environment, but a full webview/browser would be overkill.

Also, I think for the next gen native animation driver, it would be ideal to get rid of heap allocations and autoboxing from the property updates. As this can be kind of the inner loop of certain animations, it should avoid causing any garbage collection as far as possible, as that can make jitter free 60fps hard to achieve.

fkgozali commented 6 years ago

Does this mean C++ native modules will become a first class, documented citizen of the RN universe?

This has nothing to do with Fabric. It will be covered in https://github.com/react-native-community/discussions-and-proposals/issues/40

shergin commented 6 years ago

@msand Sounds amazing!

samridhgupta commented 6 years ago

First of all, I m really excited about fabric.

But I have some questions on my mind about this. Would the existing React-Native Apps (RN 0.56) be able to upgrade to this new RN Fabric? if yes then, Would there be any breaking changes to our apps? What could be Pros and Cons of migrating our existing apps to new React-Native Fabric?

SudoPlz commented 6 years ago

I have a question. How will we know that fabric is ready? I'm following this thread, but I keep on asking myself, where are we right now? Can I start writing code using the new re-architecture?

chirag04 commented 6 years ago

This tweet from Krzysztof should give you a glimpse of fabric: https://twitter.com/kzzzf/status/1064891715457294337

kelset commented 6 years ago

@SudoPlz

How will we know that fabric is ready?

It will be properly communicated.

where are we right now?

The FB team is working on the various aspects of JSI/TurboModules/Fabric, and while doing so they are doing small tests internally.

Can I start writing code using the new re-architecture?

There are some parts of the new implementation already in master of OSS, but I highly recommend that you don't dip your toe into it for now.

If I would have to give you a rough estimate, I would say that you should not expect Fabric to be "out in the wild" in a React Native OSS release for at least a couple more months. And, again, proper communication about it will happen as the situation keeps evolving 😊

aleclarson commented 5 years ago

Will RN core consider officially supporting more platforms (eg: desktop) once Fabric is released?

elicwhite commented 5 years ago

@aleclarson, It depends what you mean by officially supporting more platforms. Facebook has no plans to maintain a React Native Windows library for example. In fact, I don't think you would want this, Microsoft is much better suited at maintaining such a thing.

However, with Fabric, more of React Native will be implemented in cross platform C++, enabling other platforms to reuse more of the behavior from core. I believe the group at Microsoft is already thinking about how much they can reuse from Fabric's C++ core.

xzilja commented 5 years ago

Background

My story with react-native today goes something like this:

I started working on a side project as a web developer, at first everything seemed very straight forward and there were no major differences from normal react workflow.

I then stumbled upon few hurdles when I needed to use third party native libraries / upgrade react-native. This led me to remove as many of third party libs as I can and deep dive into writing my own custom modules so I can update them faster. To write these efficiently I had to spend few weeks learning quirks of iOS / Android and react native bridging, as well as lvl up my ObjC and Java skills. After a while I was able to write few bridges for native sdk integrations / camera / gyroscope. It took a long while.

Question

While reading this thread I got excited about fabric, but still don't think like I fully understand it. General concept is grasped and difference with bridge architecture is clear.

But what are differences in dev experience for those of us who decide to write custom native modules / contribute back to react native?