At work, I repeatedly had to deal with the choice of a suitable technology for mobile development. Below, I tried to build and classify the main frameworks according to the approaches used, advantages and disadvantages.
If some of my information is incorrect or outdated - comments are welcome.
Any cross-platform framework is a layer of abstraction over the native platform and allows you to access only those capabilities that are directly supported by the framework.
In most cases, it is possible to expand support for the platform's capabilities by writing native plug-ins to the framework, but in some cases this can significantly complicate the development. A recent example from the acclaimed AirBnb article is React Native, which currently does not know how to work out of the box with 64-bit Android libraries.
You also need to note that native plug-ins and the main code of the cross-platform application are usually executed in different processes and the interaction between them can cause performance problems. To work with sensors, or SQLite, this is usually not a problem, but if you use, say, the OpenCV library as a native plugin and start throwing video between it and the main application, the slowdown can be significant.
First, the very presence of developers depends on the prevalence of the framework. Finding people under React Native can even be easier than with native developers, and, for example, with Flutter is much more difficult.
How much this factor needs to be taken into account depends on the tasks. Most startups may not pay attention to it, since learning a new technology is more likely a bonus for existing and potential employees. On the other hand, big business is forced to take into account the labor market.
It is believed that the likelihood that support for the cross-platform framework will end is much higher than the probability of the same event in relation to the mobile OS.
In fact, the question is quite complicated. The OS can be closed in the same way as frameworks (the example of Windows Phone is completely fresh). In addition, within the native development, individual technologies can also be closed, and sometimes the code on cross-platform frameworks has a greater survivability.
An example of this is in the field of games and multimedia - Apple is going to send the OpenGL technology back to its OS and everyone who wrote native 3D applications will have to rewrite them completely to release new versions. At the same time, for those who used cross-platform game engines (for example, Unity), the update will not require any additional effort.
Technically, hybrid-type applications are an HTML page displayed in an embedded browser. In general, the framework is not mandatory for this approach, but Cordova provides a set of plug-ins to access the capabilities of the platform, which is why they usually use it.
The hybrid approach allows you to reuse not only the skills of developers, but also code written for websites.
The number of libraries for HTML / JS significantly exceeds the number of those for native applications. Of interest, this includes, for example, Google Analytics, or a rich selection of ad networks.
By itself, modern JavaScript uses JIT compilation, is well optimized and works fast, but building an interface based on a DOM tree is not a very efficient process. Using modern JS frameworks gives an additional level of load. For weak phones and / or with the active use of interactive elements, this can be a problem.
This is a rather informal, but very important point. The site in the browser responds to gestures and is displayed a little differently from the mobile app. The most noticeable element of this sensation, the delay of 300ms when pressed, Cordova decides, but many other details remain.
On older versions of Android (prior to version 5), WebView was part of the platform and was not automatically updated. Accordingly, the use of modern browser capabilities in hybrid applications on these devices will not work.
As a result, hybrid applications either limit the minimum version of Android (leaving about 13% of devices currently), or include WebView in the application code (CrossWalk project), increasing the size of the application by several tens of megabytes.
Fast creation of one-time applications. With a substantial development budget, a hybrid approach is usually disdained.
The basis of all the main hybrid frameworks is Cordova, which provides access to native plugins. PhoneGap provides tools for building on top of Cordova, while Ionic is a framework and a set of components for building user interfaces in it.
It is important to note that with this approach, the user interface and business logic are executed in different processes that interact through a bridge (“bridge”). A number of drawbacks are associated with this.
This approach has several implementation options.
Xamarin uses C # language, compiling it into native platform code. In general, this approach provides a fairly small size of the application and a fairly high speed of work.
Most of the frameworks of this approach use javascript to handle business logic.
Xamarin not only uses native interface components, but also describes them in the format adopted for each platform.
Xamarin Forms and Appcelerator use their own set of widgets, which is converted to the appropriate interface components of each platform.
React Native uses wrappers around native interface components. Accordingly, the interface is described for each platform separately, but the method of description is one.
First, the appearance and “feel” of the application fully coincide with the native applications.
Secondly, it allows the use of native interfaces libraries in applications. Using native ads (Native Ads), focused on mobile applications, in other approaches will not work. True, for this approach, the set of relevant libraries is very limited. I only know about the support of Facebook Native Ads in React Native.
Many of the frameworks of this group are designed so that developers from other areas can learn how to create mobile applications with minimal cost. For React Native - this is React, for Xamarin - .NET, etc.
The format of this minus depends on the classification of the framework by the way the interface is described:
Xamarin allows you to use almost all the capabilities of the platforms, but you have to spend a lot of time on the interfaces for each platform. As a result, labor costs are not much less than with native development.
Xamarin Forms and Appcelerator allow you to describe interfaces only once, but they work with a very limited subset of native functionality (no more than the minimum intersection of the capabilities sets of each platform, to be formal).
React Native is in the middle, combining both shortcomings, but in a less pronounced form.
Interface Interaction Performance
This is where the factor of interface execution and business logic in different processes comes into play. When it is necessary to exchange large amounts of information at a high speed across the bridge (complex animation with high frequency), this approach can cause difficulties.
Memory leaks can occur in any application, but garbage collectors do a great job with most standard situations.
The problem with cross-platform native-interface applications is again that they are executed in two processes with separate garbage collectors. If a business logic object refers to an interface object, this interface object is not garbage, because there is a link to it from the bridge. If the interface object refers back to the business logic object, they will not be considered garbage even if there are no more references to them.
Chances to meet the problem and its scale directly depend on the application. If it actively creates and deletes objects associated with the interface (as in endless scrolling), the probability of leakage increases. If these objects are large (for example, images), the leakage effect will increase.
Actually, this problem is also present when working with native plugins, which are also executed in a separate process. But there, in most cases, either there is no such intensive manipulation of large objects, or the interaction proceeds in a strictly procedural approach, without cross-references.
Applications with a completely native interface, especially if you have experts in related technologies.
It has Facebook support and uses the approach of the most popular JS framework React, due to which it is very popular. A recent article about the refusal of AirBnb from React Native made a lot of noise, but if you are aware of the risks, it can be a very effective solution.
In addition to the main approach, it has the Xamarin.Forms library, which allows you to design simple interfaces efficiently and cross-platform. Actively supported by Microsoft. When working with ASP.NET on the server, you can also save a certain amount of work through the use of common business logic classes on the server and in the mobile application.
It is modeled on React Native for developers owning other JS frameworks (Angular and Vue.js). Less popular, but has a number of more modern solutions in architecture.
Almost all game engines use this approach, but they are beyond the scope of this article.
The principle of this approach is that the application uses its own code and its own user interface drawing.
In fact, an application that independently draws its interface performs the same operations as the OS in the native interface. In theory, it can be even faster, because There is no switching between the process and the core, but in practice other factors affect the rendering speed of a particular interface, play a much larger role.
Native applications use ready-made interface components and have some limitations in what can be done with them. In turn, applications that draw their own interface do not have such limitations and can freely mix ready-made elements with individual rendering.
These disadvantages are relevant only for applications that mimic the standard interface of the OS. As already mentioned, this approach is optimal for design interfaces and games.
Applications with this approach are forced to carry with them the code to draw all interface elements, including the conventionally standard ones. This affects both the size of the application during installation, and the RAM at work.
If the first problem can be minimized with an effective Tree Shaking (as the latest Flutter versions do), then these applications consistently lose their RAM by native memory. However, this problem is typical for other cross-platform frameworks.
By default, the application looks the same on all platforms, which can create discomfort for users. Topics are used to solve these problems, but they cannot create a feeling of a completely native application.
But there is a bigger disadvantage - with this approach, it is most difficult to use third-party interface elements created for native applications (including the previously mentioned Native Ads).
Shared applications, especially with a designer interface.
Flutter is being promoted by Google as the main cross-platform development framework and the basis for the interface of their future OS Fuscia. While the framework is very young (in the Release Preview stage) and not very common, but it is quickly gaining popularity. Uses the Dart language (compiled into native code).
It has all the pros and cons of youth - a thoughtful architecture, taking into account the mistakes of predecessors, but a rather limited ecosystem.
It is popular with desktop QT developers. JavaScript can be used in development. Without the support of large companies is not very popular.
Another not very popular framework, which is interesting, primarily because it is the only framework in the list that uses the Python language. For developers who are familiar only with this language (and there are many of them in some areas of information technology), this can be crucial.
On the work of memory in Xamarin and similar frameworks
Performance comparison of native applications, Flutter and React Native
Source: https://habr.com/ru/post/421227/