He doesn't go into what specifically the performance issues were, any techniques he used to profile his app, what third party libraries he tired or anything.
Performance issues happen all the time with native apps that don't use React Native. Optimizing is a core part of what a software engineer does. Giving up on weeks of learning without a good reason seems like a poor choice to me.
As it so happen's I have been working with a colleague of mine who just fixed a React Native performance issue relating to images on Android on older devices. The author might want to check out the following article:
https://facebook.github.io/react-native/docs/performance.htm...
Our particular issue was solved by the following:
"This is especially true when you have text with a transparent background positioned on top of an image, or any other situation where alpha compositing would be required to re-draw the view on each frame. You will find that enabling shouldRasterizeIOS or renderToHardwareTextureAndroid can help with this significantly."
Apart from the above, this article is pretty shallow, which is sad because I would love to read a good article on React Native's performance. Perhaps I will write one if people are interested.
Their (and their image library Fresco's) problem is that they make heavy use of object-finalizers, which is an error in Java and especially Android.
I reported a couple of bugs, but got dismissed:
https://github.com/facebook/react-native/issues/8711
https://github.com/facebook/react-native/issues/8780
https://github.com/facebook/fresco/issues/1363
I found this rather frustrating.
I also found out that using plain java-serialization/string over the JS/Java bridge is twice as fast compared to their homegrown memory-management written in C. Again, a bugreport, again, dismissed.
https://github.com/facebook/react-native/issues/10504
It seems that Facebook's Java programmers don't know Java very well.
Facebook's tools for Android are generally written in a way that you get the feeling one could only justify by repeating the manta "We're Facebook, these are Facebook scale problems" the whole time writing you're them. (see: Redex vs just Proguard)
Wether they 're problems worth solving again need not be evaluated.
- For Fresco, I think Balazs provided a pretty good response here on how Fresco uses the finalizers (https://github.com/facebook/react-native/issues/8711#issueco...). If you still think there's an issue here, I'll direct Balazs to this post. - For RN, I remember the issue you cited stated that using Object.finalize is 430x slower than having no finalizer, which sounds really bad until you realize we're talking about 430x slower than 5.6ns. Even though we may create thousands of these objects during a typical startup, this cost adds up to a couple of ms across startup -- since we had other ideas for more impactful perf improvement, we didn't take this on, especially since the proposed alternative at the time was to but the onus on developers to remember to manually free these objects. That being said, we've switch to using PhantomReferences internally at FB for this (which is strikes us as a better solution than either of the above), and hopefully will sync that with open source soon.
Re: bridge serialization, I'm sorry that issue fell through the cracks, I'll make sure that we follow up on it internally. I think there's a meta-issue around communication here on issues and PRs, and while there are a ton to follow up on every day, the RN team could be doing better following up on the important ones that need addressing from the team (I think the bridge serialization issue qualifies), and setting proper expectations on all others. I'll follow up on that internally as well.
I apologize on behalf of the team that it's been frustrating -- I promise we do appreciate all the help we get from the community and try to balance working on our internal goals and with the community as best as possible.
"I also found out that using plain java-serialization/string over the JS/Java bridge is twice as fast compared to their homegrown memory-management written in C"
We ran into some issues relating to this when wrapping some native code on Android. I'll pass your links on to my Android colleague.
Would definitely be interested.
This really is a fantastic platform. You really can, today, write native cross platform and web apps with the same code base. With few exceptions, everything from including native modules to upgrading is painless. The UI metaphor is fantastic, the tooling is superb, the editor support is there, the community is growing. It's a great place to be.
It's not without it's warts though. From my experience, the real problems stem from the 3rd party native modules. It's not even their fault, the platform is just moving so fast. As recently as the 0.40 release, every native module out there was broken on iOS for a short period of time. I was the first to submit PR's to two fairly widely used ones, and that was multiple days after the release. On this point, I believe this is more indicative of a community that generally doesn't upgrade their projects right away- a combination of painful prior experience and a deep seeded distaste of having to re-release their app on all stores as you can leverage a tool like Microsoft Code Push to change the bundle as long as it is compatible with the native shell.
Of the two RN projects I'm working, both have at least one dependency pinned to a Github fork I have of a project, waiting for my patches to be released. This sounds worse than it is, as the majority of native modules are hilariously small and easy to modify, but it still is worth mentioning as a point of friction today. As the community grows, I expect this will diminish.
It's critical to spend more time vetting third party React Native/Javascript libraries as the quality level varies way more than with native libraries.
As a native developer I hadn't spent a lot of time working deeply with npm. One thing to be careful about when saving packages to your project is the use of ^ versus ~. See:
http://stackoverflow.com/questions/22343224/whats-the-differ...
" the tilde matches the most recent minor version (the middle number). ~1.2.3 will match all 1.2.x versions but will miss 1.3.0.
The caret, on the other hand, is more relaxed. It will update you to the most recent major version (the first number). ^1.2.3 will match any 1.x.x release including 1.3.0, but will hold off on 2.0.0."
Considering the volatility of some third party Javascript libraries, this can cause quite a bit of pain.
It's worth doing the following in your home directory add save-prefix=~ to your .npmrc and all npm install's in the future will automatically add ~ instead of ^
React Native is a great platform but it's still very fragile, particularly on Android.
I will be happy if use React ONLY for the UI, and use swift/.net for all the rest. But merge both is problematic (as far I know).
Exist a way to achieve this? Where I can use react only for the design of the UI and fully native elsewhere?
This is a big opportunity for those who might wish to make a name for themselves by developing some top quality open source components, but I also think Facebook should do a bit more to make using the phone's core features in a very high quality way as easy as possible. Things like the camera, audio recording, video, etc., are handled only via third party libraries.
The third party open source work is improving, and I'm grateful it exists, but much of it lacks contributors. Many have large lists of unresolved issues on github.
It would be very smart choice for Facebook to put a dozen or so developers on the task of submitting high quality PRs for the top 20 open source non-facebook libraries.
I now don't have an iOS version, but in my opinion having a finished product that is already gaining traction makes up for the lost time of learning to make the same thing for iOS.
(Native iOS app developer here, dabbled in React Native and went "nope" as soon as I saw how it worked and how heavily it depended on 3rd party components.)
Digging through the api it just looks much more capable in directly calling android instead of abstracted cross platform blobs.
I first tried the Angular version before the final version of Angular was released and I recall occasions where the documentation for NativeScript was behind the actual API. I had to look at the actual code samples to figure out the correct APIs.
The next time I looked at it, I tried the regular JavaScript version and I recall having trouble deciphering the API for the SideBar plugin.
This left me feeling a bit insecure about the product. It looks to have a lot of potential though but it could use a bit more polish and better documentation.
var button = new Button(...);
// Set the common properties:
button.backgroundColor = ...;
button.text = ...;
if (iOS) {
// Set iOS-specific properties
} else { // Set Android-specific properties
}The variable is app.ios / app.android
So that, for instance, you can be sure exactly when the resources for an image have been deallocated.
Perhaps I'm misunderstanding your concern, but it doesn't look like js allocates for the actual object just a proxy for the java.
Whether using RN or java, you'll want to know how to debug memory/performance issues on Android - they're mostly unavoidable on mobile devices!
(And maybe you can file some issues against React Native, too, which would be great and help the platform)
And using ReactNative or NativeScript for the high level UI and a plug-in to handle pushing the bits around is probably still a better choice than going completely native.
I thought maybe the problem was that the app had to switch to another app to select the image. I reimplemented the code using a pure JavaScript plugin based on React Native's CameraRoll API to avoid switching apps and it still crashed when the image was selected for processing.
Aa a follow up, I just did a test with a native Android app doing the same thing: getting an image through an Intent. With the native Android app, the same image that was crashing the React Native app doesn't cause any problems.
Activities/Intents should at least force you to be careful and not to keep all data around in your memory, but only pass data you really need.
https://facebook.github.io/react-native/docs/performance.htm...
It might help with some of the performance issues you encountered.
Even if you decide to abandon React Native and just do Native Android or iOS, you are going to have to deal with performance issues at some point in your career.
I would use a Content Provider to share the image instead.
https://www.youtube.com/watch?v=8N4f4h6SThc
In short, there aren't too many interpreted languages that don't rely on "native bridges" for things like UI and access to system libraries, but I wouldn't call desktop GUI frameworks for non-native languages like Java Swing or C# WinForms "native" even though they also use what you call "native components."
On the other hand, I would consider iOS Objective-C/Swift, Android NDK, and MFC/QT/GTK+ in compiled languages like C++, Rust, etc. to be truly "native" (but not Android Java, of course).
React "Native" is still very much interpreted code (if anything, RN is a different kind of "browser" that runs JS code -- yes, the JS that runs in browsers still has the same "orchestration" role that you've described from an architecture standpoint).
Given that you believe this is a memory-related problem, perhaps it's because the image is too large to fit into the available memory, and having React Native made it worse.
"Given that you believe this is a memory-related problem, perhaps it's because the image is too large to fit into the available memory, and having React Native made it worse. "
This is precisely what I think it is.
All that said, I'd still recommend going native or React Native if 1) you can afford it (time/money/properly skilled employee), or if 2) the app's needs are beyond what a 'typical' in-browser web app does.
In regards to the latter I've found quite a number of plugins that let you do notifications, or use the accelerometer, but on the whole I've found that cordova plugins can be finicky. Plus, the more plugins I need to add and the more native functionality I need to use, the more nervous I get about not fully grasping the underlying stuff.
Basically, I used to think Cordova was never really an acceptable option, especially with the release of React Native. Now, I think there are plenty of situations where it's the best solution for a client.
https://kelvinpompey.me/tempted-to-abandon-react-native-for-...