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 Native Fabric (UI-Layer Re-architecture) #4

Closed
kelset opened this issue Jul 31, 2018 · 171 comments
Closed

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

kelset opened this issue Jul 31, 2018 · 171 comments
Labels
👓 Transparency This label identifies a subject on which the core has been already discussing prior to the repo

Comments

@kelset
Copy link
Member

kelset commented Jul 31, 2018

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

  • JSI: JavaScript Interface, it's a unified lightweight general purpose API for (theoretically) any JavaScript virtual machine. It enables every other piece of the rearchitecture. (dedicated issue)
  • TurboModules: re-architecture of NativeModules, also using JSI. (dedicated issue)
  • CodeGen: a tool to "automate" the compatibility between JS and native side. (dedicated issue)

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.

@kelset kelset added the 👓 Transparency This label identifies a subject on which the core has been already discussing prior to the repo label Jul 31, 2018
@axe-fb
Copy link
Collaborator

axe-fb commented Aug 2, 2018

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
Copy link

shergin commented Aug 16, 2018

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:

  • Using C++ for cross-platform "shadow" layer;
  • Immutable data structures (Shadow Trees, Props, Events);
  • Shared memory ownership (between JS and native);
  • JSI as an interop layer between JavaScript and native;
  • Type-safe data structures;
  • Opt-in synchronous execution where it benefits performance, the UI responsiveness and simplifying inherently-synchronous interop APIs.

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

@aleclarson
Copy link

aleclarson commented Aug 22, 2018

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
Copy link

shergin commented Aug 25, 2018

@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:

  • Serializing/Deserializing pipeline;
  • Queueing;
  • Native Module API;
  • Asynchronous calling API;
  • (kinda special) Synchronous calling API;
  • Something else; Bridge is huge.

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:

  • Expose some native objects as JS objects and vice-versa;
  • Expose API for synchronous calling on this object in both directions.
    Everything else should be built on top of that.

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
Copy link

kay-is commented Aug 27, 2018

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
Copy link

shergin commented Aug 27, 2018

@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
Copy link

kay-is commented Aug 27, 2018

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
Copy link
Collaborator

axe-fb commented Aug 27, 2018

@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
Copy link

AlicanC commented Aug 27, 2018

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
Copy link

aljs commented Aug 28, 2018

  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
Copy link

shergin commented Aug 28, 2018

@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
Copy link

msand commented Sep 1, 2018

  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
    Support Interpolation of strings when using native driver in Animated, fix Expected node to be marked as "native", optimize AnimatedNode creation and connections facebook/react-native#18187
    Native animation, ClipPath spec conformance, Pattern element, Mask element, cache invalidation software-mansion/react-native-svg#757
  3. Will there be improved support for writing native modules in C++?

@axe-fb
Copy link
Collaborator

axe-fb commented Sep 1, 2018

@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 - #11

@msand
Copy link

msand commented Sep 1, 2018

@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
Copy link

msand commented Sep 1, 2018

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
Copy link

shergin commented Sep 5, 2018

@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
Copy link
Member

sibelius commented Sep 5, 2018

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
Copy link

aljs commented Sep 7, 2018

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
Copy link

mattgperry commented Sep 16, 2018

@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
Copy link

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:

  • onLayout() is an async event from native to JS, so unless native guarantees that the event is dispatched synchronously after native layout, there’s no guarantee that the content is final.
  • One of use cases that Fabric can enable is “synchronous initial rendering”, where UI layout happens synchronously until content is ready to be displayed - we’ll tackle this a bit later after the core of Fabric and its parity with existing impl are stable.
  • Now, it is in theory possible to update the behavior of onLayout() to be more synchronous in nature, or to avoid the need of initial onLayout() if native can provide layout info synchronously on mount. We are thinking about this, but it won’t be immediately changed via Fabric project. It’s more of improvements we can do on top of Fabric.

Hope that helps.

@kyashrathore
Copy link

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
Copy link

shergin commented Oct 8, 2018

@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
Copy link

joonhocho commented Oct 8, 2018

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
Copy link

shergin commented Oct 9, 2018

@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
Copy link

joonhocho commented Oct 9, 2018

@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?

@numandev1
Copy link

numandev1 commented Aug 13, 2021

@terrysahaidak for android they are using System.getenv('USE_FABRIC') REF. you can export export USE_FABIC=1 from terminal or can include in zshprofile or bash file to test fabric in android

or simple you can enable fabric in android by enableFabric:true on this file REF

@RenderCoder
Copy link

I've recently run RNTester with fabric and was really impressed.
Here is a video of rendering a screen with a flatlist within a frame.
This is amazing. It's really fast.

2021-08-11.10.52.29.mp4

In order to run it you need:

clone react-native repo
cd react-native
yarn
cd packages/react-native-codegen
yarn build
cd ../rn-tester
yarn
USE_FABRIC=1 pod install
xed .

Is there a config option in file to enable fabric for iOS?
And hope there is a way to detect whether fabric is used at runtime, do you known that?

Thanks

@numandev1
Copy link

@bijiabo you can pass fabric_enabled: true in your Podfile to enable the fabric like this

use_react_native!(path => config[:reactNativePath],fabric_enabled: true,hermes_enabled => true)

then you need to install pod again

@dancixx
Copy link

dancixx commented Aug 20, 2021

In production build I got this error 'react/renderer/components/rncore/EventEmitters.h' file not found. Does somebody any idea how to solve this?

Képernyőfotó 2021-08-21 - 0 02 36

@terrysahaidak
Copy link

navigate to Codegen package and remove it's lib/dist. run yarn build. then reinstall pods (remove Pods and Podfile.lock)

@alexandrius
Copy link

@bijiabo you can pass fabric_enabled: true in your Podfile to enable the fabric like this

use_react_native!(path => config[:reactNativePath],fabric_enabled: true,hermes_enabled => true)

then you need to install pod again

I don’t think this actually enables Fabric. It just enables some libraries to be included in the build

@terrysahaidak
Copy link

terrysahaidak commented Aug 23, 2021

@bijiabo you can pass fabric_enabled: true in your Podfile to enable the fabric like this

use_react_native!(path => config[:reactNativePath],fabric_enabled: true,hermes_enabled => true)

then you need to install pod again

I don’t think this actually enables Fabric. It just enables some libraries to be included in the build

Yep, such as React-Fabric, it used to add FBReactNativeSpec but now it's part of the default setup (because RN uses Codegen now for internal stuff).

In order to render you app with Fabric, you need to use FabricSurface as a RootView.

Here you can find the diff how to enable it on RN 0.65
terrysahaidak/FabricExample@9e14f91

@bojie-liu
Copy link

Is there any performance data between the Fabric renderer and the original one? Such as TTI, memory, FPS, etc.

We used RN heavily in our products. Just want to evaluate the benefit of upgrading to the latest RN with the Fabric renderer. @shergin

@aliraza-noon
Copy link

aliraza-noon commented Oct 14, 2021

@bojie-liu Fabric renderer might not impact the TTI directly but it might have some effect on memory and FPS, to improve the TTI we need to wait for TurboModules and other stuff to land which will have bigger impact.

It would be good if we can have some numbers for all of the new architecture components individually and overall to see the difference.

@simon-nicholls
Copy link

With the new architecture, I understand developing modules & components will need static types & a matching codegen (e.g. Flow/TypeScript).

Am I right in thinking that for regular app code, we can still use untyped JS, or languages with a JS backend like ClojureScript?

@terrysahaidak
Copy link

terrysahaidak commented Oct 25, 2021

@simon-nicholls library authors should provide these types in order to generate binding on build time. for app developers it's not required. you can continue using any language which compiles into js.

you can even develop the module itself in js. just the TurboModule interface should be defined in TS/flow.

@simon-nicholls
Copy link

@terrysahaidak Great, thanks. Makes perfect sense.

@nimish-kumar
Copy link

@kelset any updates on the release?

@kelset
Copy link
Member Author

kelset commented Dec 6, 2021

No updates on the rollout of Fabric at this point in time. We are still working on RN67 and dealing with an issue with Hermes 0.10

@kelset
Copy link
Member Author

kelset commented Dec 13, 2021

@Standard-Tech at ReactConf, the Facebook team said that they are planning to release the new architecture "next year" (2022). Nothing more precise than that for now, sorry

@gaodeng
Copy link

gaodeng commented Dec 13, 2021

Slightly disappointed, I had expected the new architecture to be released this year

@thymikee
Copy link
Member

FYI, Fabric is for the most part already there in the OSS repo, but it lacks documentation. The core team is working on an extensive document for library authors to adopt it. You can trace it here: facebook/react-native-website#2879 :)

@kelset
Copy link
Member Author

kelset commented Jan 11, 2022

Quick heads-up, a first version of the documentation describing the new architecture (Fabric's side) is now live in the documentation at the url: https://reactnative.dev/docs/fabric-renderer

(link also added to top post)

@MaheshNandam
Copy link

@terrysahaidak for android they are using System.getenv('USE_FABRIC') REF. you can export export USE_FABIC=1 from terminal or can include in zshprofile or bash file to test fabric in android

or simple you can enable fabric in android by enableFabric:true on this file REF

What would be the base version to test with the above changes? @terrysahaidak RN 0.65 works for android as well?

@alexandrius
Copy link

Fabric docs https://deploy-preview-2879--react-native.netlify.app

@gaodeng
Copy link

gaodeng commented Mar 1, 2022

https://twitter.com/almouro/status/1498347604064804864
With Fabric, the performance is still worse 😱 The list still becomes non scrollable.
https://github.com/Almouro/fabric-test

What is the official view on this, if this is really the case, it would be too disappointing, after all, waiting for such a long time, we really hope that the new architecture can make the performance of react native on the next level, especially the performance of FlatList.

@mrousavy
Copy link
Member

mrousavy commented Mar 1, 2022

@gaodeng Fabric is so much more than just a "faster FlatList". Fabric (and JSI) provides so many possibilities that simply would've never been possible with the current architecture.

You need to keep in mind that a React Native app on Fabric improves in lots of areas, such as uniform cross-platform code, better performance in initial renders, re-renders, and concurrent rendering.

We at Margelo are working on building a JSI list component that uses a different foundation than FlatList, and we are expecting it to be faster than FlatList and RecyclerListViewer, even on Fabric and all without providing an item layout function. This would not be possible without Fabric.

@aliraza-noon
Copy link

@mrousavy that is all fine you folks at Margelo can create separate package for list management, I guess vast majority of people using RN will use the builtin FlatList, I believe this is still worth investigating what is the cause of high cpu usage.

@thuongtv-vn
Copy link

Hi All,

I am so excited about new react-native architecture. But i am wondering how it work?

  • Will current Native Views be reused?
  • Or Native Views will be re-write with C++

@lukebars
Copy link

Hi All,

I am so excited about new react-native architecture. But i am wondering how it work?

  • Will current Native Views be reused?
  • Or Native Views will be re-write with C++

Hey, you can find everything at new architecture documentation, but basically:

  • You will be able to call C++ functions from JS via JSI.
  • You will have to add some Objective-C++, C++, etc. bits to your custom native view packages, to make them work with Fabric.

@thuongtv-vn
Copy link

Hi @lukebars

I mean from the Native part, with current native Views: Text, ScrollView... It will be replaced by new Views written by Objective-C++, C++?

Because when i compiled the RN-Tester app with fabric ENABLED. I saw the view is not working normally. Example fontVariant: small-caps not working. BUT it works with fabric DISABLED.

I guess meta teams is re-writting views by C++. Do you know the document to write a native component like that?

@kelset
Copy link
Member Author

kelset commented Jun 27, 2022

hey folks, since we have now an official deep dive discussion open on this in the ReactWG New architecture, let's close this one and make the conversation progress over there: reactwg/react-native-new-architecture#1

Remember that you can apply to the WG (in case you are not in it yet) by applying to the form in the readme.

@kelset kelset closed this as completed Jun 27, 2022
@kelset kelset unpinned this issue Jun 27, 2022
@react-native-community react-native-community locked as resolved and limited conversation to collaborators Jun 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
👓 Transparency This label identifies a subject on which the core has been already discussing prior to the repo
Projects
None yet
Development

No branches or pull requests