Uppsala universitets logotyp

UPTEC IT 21005 Examensarbete 30 hp April 30, 2021

An evaluation of Mobile Cross-platform Development using React Native and Native Android

Anton Carlsson Tysk Emil Kling Civilingenjörsprogrammet i informationsteknologi

Civilingenjörsprogrammet i informationsteknologi Uppsala universitets logotyp

An evaluation of Mobile Cross-platform Development using React Native and Native Android

Anton Carlsson Tysk Emil Kling

Abstract Instead of developing the same mobile application multiple times for different platforms, Android and iOS, there are frameworks which allow the developer to deploy an application to several platforms using the same code base. One of these frameworks is React Native, a JavaScript framework for developing mobile applications for both Android and iOS. Native Android applications are developed using Java or Kotlin. This paper evaluates React Native by comparing it to an Android application written in Java. The evaluation is done by developing an application in each of the two technologies and comparing performance. The performance is evaluated by measuring frame rate during an animation and the average time to solve computational tasks. To get accurate measurements a tool called Systrace is used. The results show that for graphical animations, applications developed using React Native have similar performance as natively developed Android applications. At the same time, React Native is not very good at pure computational tasks where natively developed Android applications perform better. Teknisk-naturvetenskapliga fakulteten, Uppsala universitet. Utgivningsort Uppsala/Visby. Handledare: Förnamn Efternamn, Ämnesgranskare: Förnamn Efternamn, Examinator: Förnamn Efternamn

Teknisk-naturvetenskapliga fakulteten Uppsala universitet, Utgivningsort Uppsala/Visby

Ämnesgranskare: Sven-Olof Nyström Examinator: Lars-Åke Norden Sammanfattning

Istället för att utveckla en mobilapplikation till Android och en till iOS kan man utnyttja olika verktyg för att utveckla flera applikationer samtidigt med en och samma kodbas. Ett sådant verktyg är multiplattform-ramverket React Native. Detta examensarbete jämför prestandan på en applikation utvecklad i React Native med en Android-applikation utvecklad i Java. Jäm- förelsen sker genom att mäta bildhastigheten under animationer och genom att mäta den genomsnittliga tiden det tar för applikationerna att utföra olika beräkningsuppgifter. Resultaten visar att applikationerna har liknande prestanda när det kommer till animeringar. Java-applikationen presterar genomgående bättre i testerna som avser beräkningsuppgifter. Slutsatsen är att React Native presterar tillräckligt bra för att vara ett rimligt verktyg för multiplattform-utveckling till mobilapplikationer. Acknowledgement

We would like to begin this thesis to give a well deserved thank you to ev- eryone who supported and helped us during this theses. Thank you Sven-Olof for giving us guidance through this journey. Also thank you the people at Consid AB who believed in us and allowed us to do this research.

Last but not least we would like to give a big thank you to all of our friends and family for all the support. This one is for you.

Anton Carlsson Tysk and Emil Kling Contents

1 Introduction 5 1.1 Cross-platform development ...... 5 1.2 Cross-platform development for mobile devices ...... 5 1.2.1 Cross-platform Native Applications ...... 6 1.2.2 Cross-platform Mobile Web Applications ...... 6 1.2.3 Cross-platform Hybrid Applications ...... 7 1.3 Purpose ...... 7 1.3.1 Problem statement ...... 7 1.3.2 Future work ...... 8

2 Background 8 2.1 Android ...... 8 2.1.1 Java ...... 8 2.1.2 XML ...... 9 2.1.3 Android Studio ...... 9 2.2 React Native ...... 9 2.2.1 JavaScript ...... 10 2.2.2 Components ...... 10 2.2.3 Rendering components ...... 10 2.2.4 Native modules ...... 13 2.2.5 Frame rate ...... 13

3 Method 13 3.1 Building the application ...... 14 3.2 Testing the UI view ...... 14 3.3 Testing the calculation view ...... 16

4 Implementation 20 4.1 UI test view ...... 20 4.1.1 Native ...... 20 4.1.2 React Native ...... 21 4.2 Calculation test view ...... 21 4.2.1 Fibonacci sequence ...... 22 4.2.2 Matrix multiplication ...... 22 4.2.3 Binary search tree insertion ...... 23 4.2.4 Array reverse ...... 25

5 Results 26 5.1 UI test ...... 27 5.2 Calculation test ...... 31 5.2.1 Fibonacci sequence ...... 31 5.2.2 Matrix multiplication ...... 33 5.2.3 Binary search tree insertion ...... 35 5.2.4 Array reverse ...... 38

6 Discussion 40 6.1 UI test ...... 40 6.2 Calculation test ...... 40

7 Related work 42 7.1 Other cross-platform frameworks ...... 46

8 Conclusion 46

A Appendix 52 A.1 Animation frame rate ...... 52 A.2 Fibonacci sequence ...... 53 A.3 Matrix multiplication ...... 54 A.4 Binary search tree insertion ...... 55 A.5 Array reverse ...... 58 1 INTRODUCTION

1 Introduction

In February 2017 Apple iOS and Android OS owned 97 percent of the mobile phone and tablet OS market share, according to NetMarketShare [21]. As the majority of mobile users are spread across two operating systems, it is not a surprise that many companies and developers mainly target the platforms running these operating systems. In order to give the majority of users access to a mobile application, it has to be supported on the Android and Apple operating systems. To develop the application separately for each is an expensive approach as it requires developers with experience of different programming languages and technologies. Native Android ap- plications are written in Java or Kotlin using Android’s frameworks while native applications for iOS are written in Objective- or Swift using Apple’s frameworks. Instead of writing the same logic in two different programming languages one solution could be to use a cross-platform framework that al- lows the developer to write the logic once and publish the application for several platforms.

1.1 Cross-platform development A piece of software that is implemented to run on more than one platform is called a cross-platform software. It can either be compiled to run on several platforms, or written using an interpreted language, or compiled to bytecode and executed using a common interpreter such as a JVM (Java Virtual Machine) [7]. The Information Project give three definitions of the term platform: hardware based, operating system based and one which is a combination of the other two [27]. This report refers to the second definition when reasoning about platforms, which states that a platform refers to the type of operating system running on a computer or device.

1.2 Cross-platform development for mobile devices Many tools have been developed to ease the mobile cross-platform develop- ment [5, 17]. Cross-platform applications can be divided into three categories, namely Native Applications, Mobile Web Applications and Hybrid Applica- tions. The common purpose of these types of applications is to be able to reuse as much written code as possible for two or more platforms.

5 1 INTRODUCTION

1.2.1 Cross-platform Native Applications An application is considered to be a native application if it is written in a language supported by the native SDK (Software Development Kit). For Android this means coding in Java or Kotlin and for iOS it means coding in Objective-C or Swift. Native applications can also be created by using a so called cross-platform SDK. A cross-platform SDK creates a new API that is build on top of one or multiple native SDKs and can thus target multiple platforms from a new unified API. This cross-platform API makes it possible to build native ap- plications in languages that are not supported by the native SDK [25].

1.2.2 Cross-platform Mobile Web Applications A mobile web application is an application that is designed to be accessed on a phone or tablet, and is running completely in a web browser. Mobile Web applications are developed using technologies such as HTML, HTML5, CSS and JavaScript.

Before the standardisation of HTML5 in 2014 [23], web applications had no access to device-specific hardware like the mobile phone camera or GPS, making it hard to build web applications that resemble native applications in terms of functionality. HTML5 provides an API which makes it possible for the developer to access a large amount of features connected to specific devices and hardware, for example push notifications, audio and location. However, there are still tasks a web application can not perform. Mobile web applications are limited to the supported features of the current web browser in use. For instance, Chrome and Firefox browsers can make the device vibrate while Safari can not.

The performance of a web application is dependent on DOM interactions as well as how heavy the application is in terms of UI (User Interface). The DOM (Document Object Model) is an object based representation of the structure and content of a web page where each object becomes a node in a tree structure. All nodes can be accessed through the tree and the content can be modified or deleted or a new child node can be added. Interactions with the DOM, such as adding or deleting content, can affect performance since these changes will require a re-render of the web page.

6 1 INTRODUCTION

Mobile web applications are easy to develop and accessible on any device by navigating to an URL through the web browser, but lack the look and feel of a native application, along with limited access to device specific fea- tures [14, 20, 30, 8, 19].

1.2.3 Cross-platform Hybrid Applications A mobile hybrid application is a combination of a web application and a native application. The web part of the application is typically built using HTML, CSS and JavaScript and is locally rendered using the mobile’s built in browser. The native part of the application is often written in JavaScript and mapped to a Native language using a framework which handles the implementation details. A hybrid application is, like a native application, downloaded and installed locally on a device but unlike a native application the actual content of the app is a web application inside a native container. A hybrid application can access all platform-specific features as well as have the look of a native application with platform specific styling. However, a hybrid application will not be able to match a native application in terms of performance due to the abstraction layers introduced [14, 20, 30].

1.3 Purpose React Native is a framework which allows the developer to write cross- platform native applications in JavaScript. React Native maps predefined components written in JSX (JavaScript XML) into native components for iOS and Android, which result in a native compiled application. Consid AB wanted to make a comparison between a natively developed Android ap- plication using Java with an application developed using the React Native framework. This paper aims to evaluate React Native as a framework and a tool to develop cross-platform applications by comparing the performance of an application built using React Native to a native Android application built using Java and XML.

1.3.1 Problem statement In this paper the following question will be investigated.

7 2 BACKGROUND

• How well does an application written in React Native perform com- pared to a native Android application written in Java in terms of UI rendering and back end calculations?

1.3.2 Future work This project did not compare the performance of React Native with iOS applications. However, we checked that the React Native application also worked for iOS.

The calculation tests could be extended to monitor CPU usage, memory usage and battery consumption during the calculations. Furthermore the development time and application size could be recorded and analysed.

This thesis focuses on the performance and development evaluation while no user tests are done. User tests could be performed in order to get data and results regarding the user experience and native feeling of the React Native application.

2 Background

In this chapter we will cover different technologies that is used for develop- ment of mobile applications. Background information as well as technical features will be discussed.

2.1 Android Development for native Android applications is usually done in Java or Kotlin and XML along with a tool called Android SDK. The SDK contains a set of development tools for debugging, an emulator, required libraries and some sample source code.

2.1.1 Java The Java programming language was developed by Sun Microsystems and released in 1995. The language is written in plain text files with a “.java” extension and later compiled into “.class” files by the javac compiler. The compiler does not create “.class” files specific for the hardware of the device,

8 2 BACKGROUND instead it is compiled into bytecode that is hardware independent. The Java Virtual Machine (Java VM), which runs all Java applications, use the bytecode to start an instance of the application. The Java VM is available on a lot of different operating systems and can thus use the same “.class” files to run the application on a vast amount of devices without having to specialize the code for each.

2.1.2 XML eXtensible Markup Language is a markup language, like HTML, that is used to store data. XML does not have any predefined tags, unlike HTML, in- stead the developer need to define the tags for the XML document. When developing Android applications the SDK provides predefined XML tags that are used to design the graphical interface. Tags are used to define compo- nents such as buttons, images and many more that Android support. In this case the developer can not use any tag name he or she desire if the Android compiler is to be able to match tags against a component.

2.1.3 Android Studio Android studio is the official IDE (Integrated Development Environment) for Android development created by Google. It is based upon Intellij IDEA, an IDE for Java development, but tailored for Android development with multiple Android specific tools.

2.2 React Native React Native is a JavaScript framework created by Facebook that is used for development of mobile applications. It is based on React, a JavaScript library for building user interfaces also created by Facebook. While React is used for creating user interfaces for the web, React Native targets mobile platforms by compiling the code to each platform. This code compilation is done by something called the bridge. The JavaScript thread sends asynchronous JSON messages that contains instruc- tions what the native thread should do. These messages are then parsed by a compiler for respective target platform that produces native code. The bridge is basically a message queue where the recipient will execute the commands when possible and can thus keep a steady 60 frames per second on the device.

9 2 BACKGROUND

When designing user interfaces with React Native the developer defines the look using a mix of JavaScript and an XML-like markup called JSX. React Native currently supports building applications for iOS and Android. [11]

2.2.1 JavaScript JavaScript was developed at Netscape in 1995 and has now become one of the most used programming languages on the web. Almost every web browser on desktop, tablets and smartphones come with a JavaScript interpreter which makes the amount of devices that can run JavaScript quite large. JavaScript is a dynamic language which means that variables are not specified by type, instead the type is defined by the value of the variable which can change during a program. The language is together with HTML and CSS the three main tools a web developer needs to master web development. When HTML and CSS defines the content and presentation of the page JavaScript controls the behaviour [9]. Since its birth JavaScript has come a long way and nowa- days the open source community is creating libraries and frameworks that allows JavaScript to be used more efficiently and extends the functionality of the language.

2.2.2 Components In React Native, the developer uses components, such as buttons or text fields, to build a user interface much like a web developer would do when de- veloping webpages using HTML. These components are translated to native elements for respective operating system. The developer is encouraged to de- sign simple and encapsulated components that manage only themselves and then combine multiple components to create a more complex UI [6]. Each component in React Native can be given multiple properties, more known as props, when they are created to specify the behaviour of the component or to pass additional data. Components also have a local state within itself which can not be modified from the outside. Changes in state or props will trigger a re-render of the component.

2.2.3 Rendering components Each component have a render function that returns a tree of React elements with all underlying components. When the state or props of a component change this will trigger a re-render and thus generate a new tree of elements.

10 2 BACKGROUND

To re-render a component that does not need to be re-rendered is an unnec- essary action and impacts performance and to prevent this React calculates the differences between the old tree of React elements with the new one, starting from the root, in order to only update the changed elements instead of re-rendering the entire tree.

If a node in the new tree is of a different type compared to the old tree then React will trigger a re-render of this node and any element below this one will be destroyed and its state will be lost. For example when React is comparing an old tree where an img tag is inside a div tag with a new tree where the img tag is inside a span tag instead, see listing 1, React will notice the difference between the old div and the new span and thus destroy the old div element and everything it contains and replace it with a new span element and re-render everything in it. Listing 1: An old tree with div tags and a new tree with span tags Old :

New: If the two elements to compare are the same type React will compare the properties of the elements and only update the affected DOM element where the properties has changed. After parsing an element React recursively go to the children of the element to do the same comparison. When adding new elements to a view it matters where the new element is inserted. For instance if there is a list containing two elements, as can be seen in listing 2, and a third element is inserted at the end of the list, listing 3, React would match the two Apple elements and the two Banana elements and then insert the Orange element without any problems. Listing 2: Initial list

  • Apple
  • 11 2 BACKGROUND

  • Banana

Listing 3: Insert at the end

  • Apple
  • Banana
  • Orange
On the other hand if the Orange element would be inserted at the be- ginning of the list, as in listing 4, React would compare the Apple and the Banana elements, in the old list, with the Orange and the Apple elements, in the new list, and see a difference which would result in a re-rendering of every element instead of just an insertion and keeping the Apple and Ba- nana element. This is not very efficient but can be avoided by using the key property. Listing 4: Insert at the beginning
  • Orange
  • Apple
  • Banana
The key property allows React to compare elements to each other better. If an Orange element would be inserted to the same old list using keys it would look something like listing 5. By using the keys React would know that it could keep the old Apple and Banana element and only insert Orange at the beginning of the list [29]. Listing 5: An old and a new tree of elements using keys to match elements Old :
  • Apple
  • Banana

New:

12 3 METHOD

  • Orange
  • Apple
  • Banana

2.2.4 Native modules Although React Native supports many features in respective platform, An- droid and iOS, sometimes React Native does not have a module for a specific task. The developer might want to reuse already existing code instead of rewriting it in JavaScript or implement something that React Native does not yet have. Therefore React Native supports the developer to write native code, for respective platform, and have full access of it from React Native [22].

2.2.5 Frame rate Modern devices strive to show 60 frames per second which gives the sys- tem about 16.67ms to prepare the next frame before it is supposed to be shown. The business logic of a React Native application is mostly run on the JavaScript thread, unless the developer uses native modules. At the end of each iteration of the event loop updates are sent over the bridge to the native side to update the view. If the JavaScript thread is busy when this is supposed to happen it is considered as a dropped frame and the application will appear to stutter. The overhead introduced with React Native might affect the frame rate of the application [26].

3 Method

To compare the performance of React Native and Android we made two im- plementations for the same application, one made with React Native and one made in Java for native Android. The intention was to make a fair assess- ment and to determine the strengths and weaknesses of React Native and native Android.

The application has two different views, each made for a specific task. In

13 3 METHOD this paper the term view is used to describe a single screen of the applica- tion. The first view consists of a number of squares that animates and will test the devices’ ability to maintain 60 frames per second. We call this view the UI view. The second view is where the device will perform heavy calcu- lations as fast as possible to see if any technology is superior at crunching numbers. We call this view the calculation view.

Each test is made on three different devices, two Android devices and one iPhone 7. The Android devices that were used are a LG Nexus 5X and a Sony Xperia Z2. Since this thesis focus on native Android development ver- sus React Native no native iOS application were developed. The iPhone was used as a proof of concept to make sure that the React Native application worked as intended on both platforms.

3.1 Building the application To develop the native Android application Android Studio was used since it is the official IDE for Android development and comes with multiple tools to ease development. For development of the React Native application the text editor Atom was used and compilation was made using the React Native command line tools.

3.2 Testing the UI view The UI view renders a specified number of squares on the screen. Tests were made rendering 100, 200, 300, 400 and 500 squares. For each number of squares the frame rate over 10 measurements was recorded.

Using a tool called Android Device Monitor that is included in Android Studio we analysed three applications running on the LG Nexus 5X, Face- book version 186.0, Google Photos version 3.4.0 and Instagram version 59.0 to see how many elements that were on the screen. According to our measure- ments Google Photos contained the most elements of the three with a total of 50 different imageViews displaying pictures as shown in figure 1. Even though the device only could display 40 of them at a time the view hierarchy contained a total of 50 imageViews that had been created. Instagram came second with about 25 different elements and Facebook had around 17. In the Instagram and Facebook applications, most of the elements displayed

14 3 METHOD were static images that were not animated in any way. In Google Photos every image that is shown has a small animation when zooming in or out by pinching with the fingers. One can assume that most applications does not require more than 100 different elements to be created and animated. With this in mind, a test that animates 100 to 500 elements seems quite extreme but to really test the limits of each technology the amount of elements to animate had to be challenging.

In the UI test we monitor the frame rate during an animation with the help of a tool called Systrace [24]. Systrace is a built in tool in Android Studio that allows the developer to capture a trace of what is happening on the device during a specified period of time. A trace may contain information about what each thread is doing at a specific time, for example when a new frame is displayed. The tool returns an HTML file with information about the trace as can be seen in figure 2. The trace shows when activities are started and when new frames are displayed. Multiple indicators for a new frame can be selected in the trace in order to see how many new frames there were over a selected time frame and thus the average frame rate can be calculated.

We based this thesis on the measurements we got from Systrace because we could use the same tool for both the native Android application and Re- act Native application. To confirm our measurements we used another tool called FlowUp for the native application. With a few lines of code FlowUp collects information about the device and when the device connects to a WIFI-network it synchronises the data with the FlowUp service. Informa- tion about the application is presented on a dashboard on the FlowUp website where it shows frames per second, frame time, CPU usage, memory usage, internal storage usage and more. An example of the dashboard can be seen in figure 3.

To measure the frame rate on the iPhone an iOS specific tool called in- struments [16] was used. The tool allows to make similar traces of a device like the Systrace tool can do for Android. These traces shows frames per second for the device over the measured period. An example of a trace can be seen in figure 4.

15 3 METHOD

Figure 1: The Google Photos application presenting pictures in a grid.

3.3 Testing the calculation view To measure the time it takes for the device to perform heavy calculations four different tasks were assigned to the device to compute. The calculation view contains four buttons that each start one of the different tasks. These tasks are to calculate the nth number in the Fibonacci sequence, multiply two n-times-n matrices, create a binary search tree with size n and reverse an array of size n. These four tasks were not selected because they are quick but rather because they are well known algorithms and easily implemented in multiple programming languages. Each task is done ten times with the same value of n to get the average time to finish the task, and the same task is done with twelve different values of n. The values of n are chosen in a

16 3 METHOD

Figure 2: The Systrace tool can show a lot of information regarding an application, one important piece of information are the “dots” in green, yellow and red that represents different frames. range such that the first experiment take a couple of milliseconds, the last n take a couple of seconds to complete and the rest of the values of n are divided evenly in between.

17 3 METHOD

Figure 3: The FlowUp dashboard presenting different information about the application such as average frame rate.

18 3 METHOD

Figure 4: The Instruments tool show the frame rate for a device over a period of time.

19 4 IMPLEMENTATION

4 Implementation

In this section the design and implementation of the two views in each version of the application will be discussed. The goal was to create two applications as similar as possible in look and behavior using the two technologies thus making a comparison relatively fair. The code quality of an application can impact the performance heavily if not done correctly. Therefore we strived for simplicity and known methods when developing the two versions. For React Native we used version 0.42.0 and for native Android we used SDK version 23.

When implementing the native version of the application mainly two ideas from Hervé Guihot’s book [13] were used: running tasks on a background thread, chapter 5, and keeping the layout flat, chapter 8.

The React Native application was developed following the component and container pattern. The idea of the pattern is to segregate UI components from the business logic in order to achieve re-usability of code and ease of testing. This is ideally done by declaring smaller “dumb” components such as buttons, headers or lists without any logic, and then have containers using the components and populate them with different data depending on the use case.

4.1 UI test view In the UI test view a grid of n squares are animated. The implemented ani- mation fade each square separately by changing its opacity from 0% to 100% over a four second duration.

The goal was to keep the layouts as flat as possible to reduce the num- ber of objects to be rendered. The time it takes to render a layout depends on the complexity and therefore making the layouts less complex can affect the performance of an application.

4.1.1 Native Initially the view consists of an empty GridLayout which is one standard layout in Android that will arrange children of the view in a grid. An at-

20 4 IMPLEMENTATION tribute called columnCount defines how many columns the grid will have before a new row will be created when new objects are added. By using a GridLayout the application can add multiple objects to the view and each one is displayed nicely in a grid. When the empty view is loaded multiple ImageViews are created but not displayed. An ImageView is a relatively simple class in Android that is used to display an image on the screen by supplying a resource [15]. These Im- ageViews are given the shape of a square to display and also given individual animations. When all ImageViews are created they are added to the view.

4.1.2 React Native When the UI view is opened a number of animations are created. The anima- tions are created using the Animated library [28] from React Native. Every animation is created as an Animated.View object and stored in an array be- fore starting them. This is done to make sure that every animation is created before the first one starts. Then each animation is started at the same time to make them run simultaneously. It is important that the option for using the native driver is enabled, this is done by setting useNativeDriver: true in the animation configuration options. This will make the application send all the information needed to perform the animation over the bridge to native before starting the animation. The animation is then executed on the UI thread without the need to pass over the bridge for every updated frame. This will make the animation run more smooth and allow the JavaScript thread to be blocked without interfering with the animation.

4.2 Calculation test view The calculation test view has a very simple interface since the interesting part is what happens behind the scenes. In this view there are four buttons that each start a different task for the device to perform. These tasks are to compute the nth number of the Fibonacci sequence, multiplying two n-times- n matrices, populating a binary search tree with n nodes and to reverse an array of length n. n is taken from an input field in the application and when the task is done the time it took is displayed in milliseconds.

Hervé Guihot talks about the importance of running tasks on a background thread instead of the main thread to keep the application responsive. When

21 4 IMPLEMENTATION a to start the calculation is pressed the device will start a custom class specific for each task. These custom classes extend the AsyncTask [2] class which allow tasks do be done on a background thread and hence making the device do the calculation without blocking the main thread.

4.2.1 Fibonacci sequence The task to calculate the nth number in the Fibonacci sequence is done using recursion. The code for the native implementation can be seen in listing 6 and the React Native code can be seen in listing 7. Listing 6: The Java code for the recursive Fibonacci private int f i b ( int i ) { i f ( i <= 2) { return 1 ; } return f i b ( i − 1) + f i b ( i − 2 ) ; }

Listing 7: The JavaScript code for the recursive Fibonacci f i b(n){ i f (n <= 2) return 1 ; return this .fib(n −1) + this .fib(n −2) }

4.2.2 Matrix multiplication When multiplying two n-times-n matrices the first matrix is populated using the sequence of numbers generated by (i+1)∗(y+1) and the second matrix is populated by the sequence of numbers generated by (x∗x)−((i+1)+(y+1)) where i, j ∈ {0,...,N − 1}. i represents the index of the columns and j represents the index of the rows. The Java code for the multiplication can be seen in listing 8 and the JavaScript code can be seen in listing 9. Listing 8: The Java code for the matrix multiplication for ( int i=0;i

22 4 IMPLEMENTATION

int tempResult=0; for ( int z=0;z

Listing 9: The JavaScript code for the matrix multiplication f o r(i=0;i

4.2.3 Binary search tree insertion When populating the binary search tree the keys to be inserted are generated by the expression ((sin(i) − sin(i + 1)) ∗ 1000) where i ∈ {1,...,N}. The native Java implementation of the insert function can be seen in listing 10 and the React Native implementation can be seen in listing 11. Listing 10: The Java code for the binary search tree insertion public void i n s e r t( int data){ Node newNode= new Node(data); i f (root == null ){ root= newNode; return ; } else {

Node current= root;

while (current != null ){ i f (data< current.getData()){

23 4 IMPLEMENTATION

i f (current.left != null ){ current= current.getLeft(); } else { current.left= newNode; return ; } } else { i f (current.right != null ){ current= current.getRight(); } else { current.right= newNode; return ; } } } return ; } }

Listing 11: The JavaScript code for the binary search tree insertion i n s e r t(value){ var node={ value: value, l e f t: null , r i g h t: null } i f ( this .root == null ){ this .root= node; return ; }

var current= this .root

while (current != null ){ i f (value< current.value){ i f (current.left != null ){ current= current.left; } else {

24 4 IMPLEMENTATION

current.left= node; return ; } } else { i f (current.right != null ){ current= current.right; } else { current.right= node; return ; } } } }

4.2.4 Array reverse The array reverse algorithm is implemented recursively. The head of the array is concatenated with a recursive call on the tail of the array. One difference here is that the Java version makes use of an accumulator while the JavaScript does not. The native Java implementation can be seen in listing 12 and the React Native implementation can be seen in listing 13. Listing 12: The Java code for the array reverse private int [] reverseArr( int [] arr, ArrayList acc){ i f (arr.length == 0) { return ArrayUtils .toPrimitive(acc.toArray( new I n t e g e r[acc.size()])); } int []h= Arrays. copyOfRange(arr, 0, 1); int []t= Arrays. copyOfRange(arr, 1, arr.length); acc.add(0,h[0]); return reverseArr(t, acc); }

Listing 13: The JavaScript code for the array reverse r e v e r s e(arr){ i f (lst. length == 0) {

25 5 RESULTS

return []; } const[head,... tail]= arr; return this .reverse(tail).concat([head]); }

5 Results

In this section the results from the UI test and the calculation tests are pre- sented and discussed. All tests were made on both the native and the React Native application. The native application was tested using two Android de- vices and the React Native application was tested on the same two Android devices and one iOS device. All the results presented are an average taken of ten measurements. The measurements made on the iPhone 7 are separated from the Android measurements since there is no native iOS application to compare them to. All measurements for the figures in this section are listed in the appendix as tables 2 - 16. The devices used are listed below. Listing 14: LG Nexus 5X OS Android 7.1.2 (Nougat) Chipset Qualcomm MSM8992 Snapdragon 808 CPU Hexa−core (4x 1.4 GHz Cortex −A53& 2x 1.8 GHz Cortex −A57) GPU Adreno 418 Memory2 GB RAM Release October 2015

Source: http://www.gsmarena.com/lg_nexus_5x-7556.php Listing 15: Sony Xperia Z2 OS Android 6.0.1 (Marshmallow) Chipset Qualcomm MSM8974AB Snapdragon 801 CPU Quad−core 2.3 GHz Krait 400 GPU Adreno 330 Memory3 GB RAM Release April 2014

Source: http://www.gsmarena.com/sony_xperia_z2-6144.php

26 5 RESULTS

Listing 16: iPhone 7 OS iOS 10.3.2 Chipset Apple A10 Fusion CPU Quad−core 2.34 GHz (2x Hurricane+2x Zephyr) GPU PowerVR Series7XT Plus(six −core graphics) Memory2 GB RAM Release September 2016

Source: http://www.gsmarena.com/apple_iphone_7-8064.php

5.1 UI test The UI test was made by measuring the frame rate during an animation. The measurements were made on both the native application and the React Native application.

In the UI test, the React Native application with the LG Nexus 5X per- forms the best, as can be seen in figure 6, by only dropping from an average of 57.85 FPS to 50.73 FPS when the amount of squares increase from 100 to a total of 500. The Sony Xperia Z2 drops from an average of 58.25 FPS to 26.03 when the number of squares increase from 100 to 500.

The results of the native application can be seen in figure 5.

In figure 7 the average native frame rate and the average React Native frame rate can be seen. Again, the average frame rate of React Native is only based on the two Android devices and not the iPhone.

By looking at figures 5 - 7 one can see that the React Native application has an overall higher frame rate during the animation compared to the na- tive Android implementation. Figure 5 and 6 show that both the Nexus 5X and the Xperia Z2 performs similar on both implementations of the anima- tion. The Z2 drops quite a lot of frames when the number of squares are increased while the 5X manages to keep above 50 FPS even for 500 squares when running the React Native application. There are however a few as- pects to take into consideration when looking at these results. First of all the native animation is fully implemented by the authors in Java, while the React Native animation is implemented with the help of Animated, a library

27 5 RESULTS developed by Facebook. By using the Animated library for the React Native application the programming skills of the authors do not influence the per- formance of the animation as much as it does when developing the animation for the native Android application.

Furthermore before the animation starts there is sometimes some stutter directly after navigating to the UI view. The React Native Animated library introduces some overhead when creating Animated objects. This causes the animation to have a significant delay before starting and might cause some stutter. The measurements made for this thesis focused on the frame rate of the animation itself and not the moments before or after. When the number of objects to animate increases React Native does not start the animation as fast as the native Android application as a consequence of overhead when creating the objects.

Another option that causes the React Native animation to take longer time before firing off is when the flag useNativeDriver is set to true which causes the animation to be pre-computed before being sent to the UI thread. It is possible to set useNativeDriver to false which will speed up the starting process of the animation but will instead cause the animation to stutter a lot due to the large amount of updates of the animation that has to be sent over the bridge to the UI thread. In our measurements useNativeDriver is set to true to produce the smoothest animations possible.

28 5 RESULTS

Figure 5: The frame rate of the native application during animation measured on the Android devices.

Figure 6: The frame rate of the React Native application during animation measured on both Android devices and the iPhone 7.

29 5 RESULTS

Figure 7: The frame rate of the native application compared to the frame rate of the React Native application on the Android devices.

30 5 RESULTS

5.2 Calculation test 5.2.1 Fibonacci sequence Figure 8 shows the average time it takes for the devices to calculate the nth number in the Fibonacci sequence using the native Android application. The same test is done with the React Native version of the application on all three devices and the result can be seen in figure 9. Figure 10 shows the native average and the React Native average. The React Native average is only based on the two Android devices and not the iPhone.

Figure 8: The time in milliseconds taken for the Z2 and 5X to calculate the nth number of the Fibonacci sequence using the native Android application.

When it comes to native performance on the Fibonacci test both Android devices perform similar as can be seen in figure 8. The Android devices have similar performance with the React Native application as well, figure 9. The iPhone7 performs a lot better at the Fibonacci test than the other two de- vices when running the React Native application. When calculating the 41st number in the Fibonacci sequence the iPhone7 is almost 10 seconds faster than the Android devices with a speed of 14.7 seconds compared to an aver- age of 24.3 seconds by the Android devices which is a 1.65x speedup. Figure

31 5 RESULTS

Figure 9: The time in milliseconds taken for the Z2 and 5X to calculate the nth number of the Fibonacci sequence using the React Native application.

Figure 10: The time in milliseconds for the Z2 and 5X using the native Android application compared to the React Native application to calculate the nth number of the Fibonacci sequence.

10 shows that both native and React Native have acceptable performance at low values of n but when n increases React Native is the first one to reach “unacceptable” performance. The difference in speed between the two

32 5 RESULTS technologies are around a factor 2.5 for all values of n tested. The last step when n changes from 40 to 41 the native application take about 3.2 seconds longer to finish and the React Native application take about 9.8 seconds longer to finish. The lack of performance in React Native, at high values of n, can especially be seen in figure 10.

5.2.2 Matrix multiplication Figure 11 shows the average time for the two Android devices to multiply two n-times-n matrices using the native application. Figure 12 shows how the React Native application perform the same test. The average times for both applications can be seen in figure 13.

Figure 11: The time in milliseconds taken for the two Android devices to compute a matrix multiplication of two N-times-N matrices using the native application.

The matrix multiplication test gave some interesting results when it came to native performance. As can be seen in figure 11 the LG Nexus 5X performs better than the Sony Xperia Z2 on low values of n but when n reaches 260 the 5X starts to perform quite badly. More exactly the threshold was found to be when n increased from 253 to 254. After an n of 253 each measured

33 5 RESULTS

Figure 12: The time in milliseconds taken for the two Android devices and the iPhone7 to compute a matrix multiplication of two N-times-N matrices using the React Native application.

Figure 13: The time in milliseconds taken for the native Android application compared to the React Native application. steps took a lot longer time to compute. This behaviour by the 5X was unex- pected and the reason is unknown. We considered the L1 and L2 cache size and chipset model of both devices. The L1 and L2 cache sizes are the same

34 5 RESULTS size on both devices so this should not create a difference in performance. The Nexus 5X uses the Snapdragon 808 chipset, which may be causing the performance problems. According to a post [18] on the XDA-Developers’ fo- rum, Nexus 5X potentially has a problem with the chipset that can cause the device to become stuck in a bootloop. We do not know whether the Nexus 5X device used in these test suffered from problem with the chipset since it did not get stuck in a bootloop. If this is the reason though, it would explain the poor performance of the Nexus in the matrix multiplication test.

The Z2 on the other hand performs quite nicely on all values of n using the native application. This can be seen very clearly in figure 11. The Nexus 5X does not seem to have the same issue when it uses the React Native version. There is no obvious threshold where the performance starts to degrade but on the other hand the performance is significantly worse with all values of n as can be seen in figure 12. The two Android devices performs very similar with the React Native version but the iPhone is clearly the best device on this test. The average time of multiplying two 320-by-320 matrices with the Android devices is 99.3 seconds while the iPhone does it in 14.1 seconds. Figure 13 shows the performance of the native application and the React Native application and it is quite clear that the native application perform better. Again the iPhone is not included in the React Native average because it would not become a fair comparison if there were two devices representing the native version and three devices representing the React Native version. The iPhone using React Native performs fairly well compared to the Android devices though and could almost be compared to the native version.

5.2.3 Binary search tree insertion Figure 14 shows the average time for the native Android application to insert n nodes in a binary search tree. In figure 15 the average time it took to insert n nodes in a binary search tree using the React Native version can be seen. The average time for the native application and the React Native version can be seen in figure 16. In this test the Sony Xperia Z2 performs a little bit better than the LG Nexus 5X on all values of n when using the native Android version. When the two Android devices do the test using the React Native version they are very equal in performance as can be seen in figure 15. Like the previous tests the iPhone perform very well in this one as well.

35 5 RESULTS

While the Android average using React Native for inserting 120 000 nodes in a binary search tree is 2.47 seconds the iPhone can do it in 0.65 seconds. Figure 16 compares the native Android application with the React Native version.

Figure 14: The time in milliseconds taken for the two Android devices to in- sert n number of nodes in the binary search tree using the native application.

36 5 RESULTS

Figure 15: The time in milliseconds taken for the two Android devices and the iPhone7 to insert n number of nodes in the binary search tree using the React Native application.

Figure 16: The time in milliseconds taken for the native Android application compared to the React Native application.

37 5 RESULTS

5.2.4 Array reverse The average time for the native Android application to reverse an array of length n using a recursive algorithm can be seen in figure 17. The time it took for the React Native version can be seen in figure 18. Figure 19 shows the average time it took in milliseconds for the native version and the React Native version to reverse an array.

Figure 17: The time in milliseconds taken for the two Android devices to reverse an array of length n using the native application.

In this test the Android devices performs well, using the React Native appli- cation, while the iPhone does not manage to perform the task at all. When the iPhone tries to reverse an array of 2333 elements or more the application crashes due to a “Maximum call stack size exceeded”. This does not happen on the Android devices even though they run the same code and thus it must be iOS specific.

38 5 RESULTS

Figure 18: The time in milliseconds taken for the two Android devices and the iPhone7 to reverse an array of length n using the React Native application.

Figure 19: The time in milliseconds taken for the native Android application compared to the React Native application.

39 6 DISCUSSION

6 Discussion

6.1 UI test It is important to keep in mind that the tests are made with the purpose of comparing the two technologies and push them to the max, which has re- sulted in quite many squares being animated. As can be seen from the mea- surements React Native performs well in the UI test for both devices, except when the flag useNativeDriver is set to false while configuring the animations which causes the animation to stutter. More about the flag useNativeDriver in section 4.1.2. The bridge is the bottle neck when developing applications in React Native. Therefore the developer should put some thought into min- imising the passes over the bridge. This can for example be done by avoiding unnecessary updates of the UI. As a solution to this problem React Native offers the developer the ability to write native modules in Java or Kotlin and Objective-C or Swift.

6.2 Calculation test Implementing the same tests in different languages may impact the results due to different programming paradigms being more suitable for certain lan- guages. The four calculation tests implemented in this thesis each strive to be logically identical in respective language, i.e performing the same opera- tions in Java and JavaScript. By looking at the implementations in listings 6 - 13 one can conclude that the tests for the Fibonacci sequence, matrix multiplication and binary search tree insertion are logically identical in their respective language. The array reverse test has a slightly different implemen- tation in Java and JavaScript since the Java version of the test makes use of an accumulator while the JavaScript does not. This makes it hard to draw conclusions in the array reverse comparison.

Overall the native application had the best performance compared to the React Native application, but when React Native was run on an iPhone the performance was significantly better than both Android devices running the same code. The iPhone running the React Native application failed the array reverse test but at the same time performed better then the other de- vices in the Fibonacci, matrix and binary search tree test. One reason why the iPhone was faster than the Android devices when running React Na-

40 6 DISCUSSION tive might be that the Android devices used in these tests are a couple of years older than the iPhone. While the iPhone was released in late 2016 the newest Android device used was the LG Nexus 5X which was released about a year before that and the Sony Xperia Z2 about 2.5 years before the iPhone.

Even though the native application was faster than the React Native ver- sion it is important to not only look at the difference in time but also look how they perform when the problem grows. Table 1 presents a factor value that is calculated by F = Trn where T is the time for the React Native Tn rn application to solve a task and Tn is the time it took for the native Android version to solve the same task. When looking at the speed difference as a factor instead of time React Native is still behind the native version but the factorial difference does not change much as n increases. For instance when calculating the ntn number in the Fibonacci sequence React Native is initially 2.28 times slower than the native version and as n increases to 41 React Native ends up being 2.77 times slower. For this test the React Native is on average 2.47 times slower than the native version. In the binary search tree test and array reverse test the relative difference in performance does not vary much for different values of n. One test that differs from the oth- ers is the matrix multiplication test where the relative difference drastically changed between n=240 and n=260 where the native solution became a lot slower. This is due to strange behaviour of the Nexus 5X discussed earlier. Also the matrix multiplication test has a high relative difference compared to the other tests.

In the calculation tests, React Native was between 1 and 3 times slower than the native version for all tests except matrix multiplication. This might indicate that Java is superior to JavaScript when performing arithmetic op- erations. Considering React Native being a mobile cross-platform JavaScript framework which introduces overhead this is acceptable. For the matrix multiplication the performance of React Native was significantly worse than native Java. React Native ended up 34.8 times slower on average than the Java version. Due to the poor performance one should consider different so- lutions to implement heavy arithmetic operations in React Native, such as implementing a native module or do heavy calculations on a back end server.

41 7 RELATED WORK

Table 1: Relative performance in speed between React Native and native, calculated by dividing React Native time by native time.

Measurement Fibonacci Matrix Binary Search Array Reverse Multiplication Tree Insertion N1 2.28 43.10 2.44 2.32 N2 2.20 44.40 2.10 2.18 N3 2.40 39.75 1.84 1.67 N4 2.44 40.75 1.68 1.77 N5 2.50 41.61 1.56 2.19 N6 2.40 40.17 1.54 2.95 N7 2.47 44.75 1.40 3.07 N8 2.46 46.50 1.38 3.29 N9 2.45 22.06 1.30 3.12 N10 2.60 19.60 1.33 3.10 N11 2.59 18.28 1.24 3.31 N12 2.77 16.58 1.19 3.51 Average 2.46 34.8 1.59 2.71

7 Related work

Oscar Axelsson and Fredrik Carlström [3] compare React Native to native mobile development. When testing native applications and React Native applications they focus on four aspects, User Experience, Reliability, Inter- action with sensors and Benchmark. To evaluate User Experience, they con- duct interviews and use questionnaires. During the interview they ask the interviewee to complete a set of tasks using two mobile devices each contain- ing an installation of a visually identical application. One device contains an application developed using React Native and the other device contains an application developed using either native iOS or native Android. After completing the tasks on a device a survey is conducted where the intervie- wee answers questions about the difficulty of the tasks, the usability of the application and the users satisfaction. To measure reliability, they test if the device and application can remain unaffected by certain interruptions that occur in everyday usage. The events tested are Incoming and Outgoing SMS and MMS, Incoming and Outgoing calls, Incoming Notifications, Cable In-

42 7 RELATED WORK sertion and Removal for data connection, Network outage and recovery and Device Energy saving mode. To test the interaction with sensors they use the devices’ GPS and accelerometer. When benchmarking the applications they observe the behaviour of the CPU, memory management, battery, network and the application size.

The developed application is divided into six parts which each contains a main feature. The features are Login, Information retrieval, Internal stor- age, Interaction with sensors, Animation and Other applications. They fur- ther divide the application into five parts which each represent a view in the application. For each feature the reliability and benchmarking tests were made. In the results they present the amount of time spent developing, and the number of lines of code written for each feature and for each view in the native Android, native iOS, and React Native application.

They show that the most time spent developing was put on React Native, however the combined time for Android and iOS development exceeds the total time spent on React Native. The native Android application required almost 1800 lines of added source code, while the native iOS application required around 1200. The React Native application required 1500 lines of source code. According to their interviews and questionnaires regarding user experience the native iOS application performed slightly better than the na- tive Android and React Native iOS application, while the Android version of the React Native application performed the worst in terms of user ex- perience. Even though the results show a difference in user experience they conclude that those differences are minimal. The results show that React Na- tive passes all reliability tests except for the Android version which fails the Device Energy Saving Mode-test due to the smoothness of animations being affected. There are no concrete results presented regarding interaction with sensors except the amount of time spent on that particular feature. For the benchmarking tests they measure CPU usage, average RAM usage and the application size. They state that the results from the network and battery tests were irrelevant and did not have any impact on the comparison. The results show that React Native used the most CPU and memory in both the Android and iOS version while the native iOS had the largest application size.

Both their thesis and our thesis cover the area of animations but with different approaches. Our thesis present the measured frame rate during animations

43 7 RELATED WORK while they present the result of user interviews along with CPU and memory usage. Their result of the animation test align with ours for low numbers of animated squares where the frame rate is close to 60 for both React Native and native. They state that the animation on Android was affected when the device energy saving mode setting was enabled. It would have been inter- esting to see how this setting and the other interruption events would affect the result of the tests covered in our thesis. Their general conclusion is that the differences between the resulting React Native and native applications are negligible and can not alone dictate whether one should chose one tech- nology over the other. They instead propose that one should consider the developers previous experience and preferences when choosing the technol- ogy. Based on our UI and calculation tests we agree with their conclusion with the addition that one should consider which type of application is to be developed.

Martin Furuskog and Stuart Wemyss [12] evaluate React Native by measur- ing performance and user experience. They implement a total of six “Hello, World!” applications, three for Android and three for iOS. Two applica- tions are implemented using React Native, two with another cross-platform framework called and the last two are implemented natively for each platform, Java for Android and Swift for iOS. With the help of these applications they compare the setup for the different development environ- ments and they document the total application size.

In their results they outline the setup process for each development method and conclude that there was no big difference of the “Hello, World!” imple- mentation. The iOS version of Xamarin had the largest file size with 32.9MB while native Android had the smallest with 5.8MB. To measure performance, the bubblesort algorithm was implemented for the same six combinations of platform and framework. The results show that the React Native performed the worst and the native versions performed the best for both Android and iOS. To test the user experience an application was developed for the same six combinations of platform and framework. The application contained a view with a to-do-list and a view with buttons and images. With the help of the application user tests and interviews were conducted. According to the results from the user tests there was no noticeable difference in the three ver- sions of the iOS application. In the Android versions some users experienced delay when performing certain actions in the React Native and Xamarin ver-

44 7 RELATED WORK sions of the application.

Finally, the front-end of a “real-life case” application was developed using only React Native. To compare the development of the application the au- thors refer to their prior experience developing native applications.

Furuskog and Wemyss base a large part of their evaluation of React Native on prior experience of developing native applications and perform perfor- mance tests on one algorithm. They measure user experience by conducting interviews based around a simple application implemented on six platforms and frameworks. While user experience is important, our thesis emphasises performance in terms of computational tasks and frame rate during anima- tions. Their results of the bubblesort test align with our calculation test results where the applications built using React Native performs worse than the others. They conclude that factors such as application complexity, time plan and development language preference has to be taken into account when choosing a framework.

Both Axelsson and Carlström, and Furuskog and Wemyss present similar results as we do in our thesis. React Native offers worse computational per- formance than a native application, but if the application does not require any heavy calculations there are no noticeable differences between a React Native application and a native application. They both report from user testing that the React Native version of the Android application performed slightly worse than the other versions. This is nothing we could observe from the UI animation test results.

John A. Calderaio [4] compares the performance of native iOS and React Native. Calderaio creates an application using each technology and then performs four different tasks where he measures CPU, frame rate and mem- ory usage. Calderaio concludes that applications using React Native and native iOS are almost identical in performance. The native iOS application was better when it comes to CPU but for frame rate and memory usage React Native performed better. While Calderaio is comparing React Native to a native iOS application the similarity to our result is that React Native performed better in terms of frame rate compared to the native implemen- tation.

45 8 CONCLUSION

7.1 Other cross-platform frameworks There are multiple frameworks that can be used to create cross-platform mo- bile applications. In this section we will mention a few and note what they can do.

Xamarin [31] is a framework from Microsoft for developing native appli- cations for Android, iOS and Windows using .NET and C#. This cross- platform framework uses C# to write the shared logic and with the help of the .NET platform and libraries access native APIs for the different devices.

Flutter [10] is a UI toolkit developed by Google that is used to develop native applications for mobile, web and desktop. The UI development is based around, so called, widgets. These widgets behave similarly to a React component and represent different UI elements that Flutter can display. The applications are written in Dart and can be deployed to Android, iOS, Linux and web. For mobile and desktop devices Dart is compiled ahead-of-time to machine code using the built in compiler while for web applications Dart is translated into JavaScript.

Cordova [1] is a framework used to create hybrid applications. It wraps HTML, CSS and JavaScript in a native container and can deploy an applica- tion to Android, iOS, OS X, Windows and Electron. Cordova provide plugins that can be used to access device capabilities such as battery, camera, etc.

8 Conclusion

Both Android devices performed better in React Native than the native ap- plication during the UI test, as can be seen in figure 5 and 6 or appendix A.1. The React Native version of the application managed to keep an average frame rate of 38.38 when animating 500 squares while the native application could only maintain an average frame rate of 24.7. On the other hand, React Native does not perform that well with pure computational tasks. We can see that React Native performed worst in the matrix multiplication, table 1, where React Native ended up 34.8 times slower than the native application on average. The other three tests, Fibonacci, Binary search tree insertion and Array reverse performs relatively well but still worse than native. Fibonacci

46 8 CONCLUSION ended up 2.46 times slower, Binary search tree insertion ended up 1.59 times slower and Array reverse ended up 2.71 times slower on React Native. The iPhone7 performed very well in most tests, as can be seen in list- ing 16, and this might be because the device is newer and the hardware is better. The Android devices used in the tests were one respectively two and a half year older than the iPhone and thus the hardware in the Android devices is quite “old” compared to the iPhone. The LG Nexus 5X which is the newest one of the Android devices generally performed better than the Sony Xperia Z2, especially in the UI test, and this might be because of the newer hardware in the 5X. Considering the results new devices with today’s hardware might be able to compete with native applications. Obviously how demanding the application is has to be taken into account. If the desired application is supposed to be light weight with few animations on the screen React Native might be the technology for the job even for older devices.

The fact that you get an application for both Android and iOS from one code base using React Native saves a lot of development effort. Sometimes it might take a few more lines of code to develop in React Native than native Android but if you add the time it would take to create the same thing in iOS the total effort of native development would be more than just using React Native. Sometimes React Native allows for easier customisation than native development and sometimes vice versa. The large community for third-party libraries can be of immense help when developing for native but especially for React Native. Already finished components that look and feel native can be included via third-party libraries easily and can save the developer some time.

If the application needs to access features that is not supported in React Native yet the developer can create a native module to include in the React Native application but if the application is in need of multiple native modules for both Android and iOS it might be better to develop a native application instead. At which point a native solution is better is not easy to say and might be up to the developer to decide if they need something very specific that React Native cannot perform. But from our experience there are very few things that React Native does not already support and new third party libraries are being developed all the time by the community.

Based on our measurements, both UI and calculation, we would conclude that React Native is very good for creating lightweight applications where

47 8 CONCLUSION heavy calculations are done on the back end.

48 REFERENCES

References

[1] Apache Cordova. Documentation. Accessed: April. 25, 2021. url: https: //cordova.apache.org. [2] AsyncTask | Android Developers. Documentation. Accessed: Mars. 28, 2017. Android. url: https://developer.android.com/reference/ android/os/AsyncTask.html. [3] Oscar Axelsson and Fredrik Carlström. “Evaluation Targeting React Native in Comparison to Native Mobile Development”. MA thesis. http://lup.lub.lu.se/student-papers/record/8886469: Lund University, Aug. 2016. [4] John A. Calderaio. Comparing the Performance between Native iOS (Swift) and React-Native. Blog post. Accessed: June. 7, 2019. url: https://medium.com/the- react- native- log/comparing- the- performance- between- native- ios- swift- and- react- native- 7b5490d363e2. [5] Sunny Dhillon and Qusay H. Mahmoud. “An evaluation framework for cross-platform mobile application development tools”. In: Software: Practice and Experience 45.10 (Jan. 2015), pp. 1331–1357. [6] Bonnie Eisenman. Learning React Native: Building Native Mobile Apps with JavaScript. O’Reilly Media, 2015. isbn: 9781491929070. url: https: //books.google.se/books?id=274fCwAAQBAJ. [7] Encyclopedia: cross platform. Accessed: Mars. 10, 2017. PC Maga- zine. url: https://www.pcmag.com/encyclopedia/term/cross- platform. [8] Andy Favell. Web apps: bringing the advantages of native apps to a web browser. Article. Jan 2016. url: https://www.clickz.com/web- apps- bringing- the- advantages- of- native- apps- to- a- web- browser/90689/. [9] David Flanagan. JavaScript: The Definitive Guide: Activate Your Web Pages. 6th ed. O’Reilly Media, Inc, 2011. [10] Flutter - Beautiful native apps in record time. Documentation. Ac- cessed: April. 25, 2021. url: https://flutter.dev.

49 REFERENCES

[11] Marvin Frachet. Understanding the React Native bridge concept. Artice. Accessed: Jan. 15, 2020. url: https://hackernoon.com/understanding- react-native-bridge-concept-e9526066ddb8. [12] Martin Furuskog and Stuart Wemyss. “Cross-platform development of smartphone applications: An evaluation of React Native”. MA thesis. http://uu.diva-portal.org/smash/record.jsf?pid=diva2%3A948617&dswid=6085#sthash.ak4MjhnT.dpbs: Uppsala University, Aug. 2016. [13] Herv Guihot. Pro Android Apps Performance Optimization. 1st ed. Apress, 2012. [14] Henning Heitkötter, Sebastian Hanschke, and Tim A. Majchrzak. Eval- uating Cross-Platform Development Approaches for Mobile Applica- tions. In: Cordeiro J., Krempels KH. (eds) Web Information Systems and Technologies. WEBIST 2012. Vol. 140. Lecture Notes in Business Information Processing. Springer, Berlin, Heidelberg, 2013. [15] ImageView | Android Developers. Documentation. Accessed: Mars. 27, 2017. Android. url: https://developer.android.com/reference/ android/widget/ImageView.html. [16] Instruments User Guide: About Instruments. Documentation. Accessed: July. 19, 2017. Apple. url: https://developer.apple.com/library/ content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/ index.html. [17] Wafaa S. El-Kassas. “Taxonomy of Cross-Platform Mobile Applications Development Approaches”. In: Ain Shams Engineering Journal (Oct. 2015). [18] Doug Lynch. Nexus 5X Bootloop Fix Finally Lets You Boot the Phone. Forum post. Accessed: September. 16, 2017. XDA-Developers. url: https : / / www . xda - developers . com / nexus - 5x - bootloop - fix - boot-phone/. [19] Mobile HTML5 compatibility on iPhone, Android, Windows Phone, BlackBerry, Firefox OS and other mobile devices. Documentation. Ac- cessed: July. 2, 2019. url: https://mobilehtml5.org/. [20] Mobile: Native Apps, Web Apps, and Hybrid Apps. Article. Accessed: April. 15, 2020. Raluca Budiu. url: https://www.nngroup.com/ articles/mobile-native-apps/.

50 REFERENCES

[21] Mobile/Tablet Operating System Market Share. Accessed: Mars. 8, 2017. NetMarketShare. url: https://www.netmarketshare.com/operating- system-market-share.aspx?qprid=8%5C&qpcustomd=1. [22] Native Modules. Documentation. Accessed: April. 15, 2020. Facebook Inc. url: https://reactnative.dev/docs/native-modules-ios. html. [23] Open Web Platform Milestone Achieved with HTML5 Recommenda- tion. Recommendation. Accessed: Mars. 13, 2017. World Wide Web Consortium. url: https://www.w3.org/2014/10/html5-rec.html. en. [24] Overview of system tracing | Android Developers. Documentation. Ac- cessed: May. 12, 2017. Android. url: https://developer.android. com/topic/performance/tracing/. [25] Ritesh Patil. Pros and Cons of Cross-Platform Mobile App Develop- ment. Article. Sep 2016. url: https://www.infoq.com/articles/ mobile-cross-platform-app-development. [26] Performance Overview. Documentation. Accessed: April. 15, 2020. Face- book Inc. url: https://reactnative.dev/docs/performance.html. [27] Platform definition by The Linux Information Project. Definition. Ac- cessed: Mars. 10, 2017. The Linux Information Project. url: http: //www.linfo.org/platform.html. [28] React Native Animated. Documentation. Accessed: Aptil. 15, 2020. Facebook Inc. url: https : / / reactnative . dev / docs / animated . html. [29] Reconciliation. Documentation. Accessed: April. 15, 2020. Facebook Inc. url: https://reactjs.org/docs/reconciliation.html. [30] Robert Sheldon. Understanding HTML5 mobile application develop- ment. Article. Jan 2016. url: https : / / searchmobilecomputing . techtarget.com/feature/Understanding-HTML5-mobile-application- development. [31] Xamarin | Open-source mobile app platform for .NET. Documentation. Accessed: April. 25, 2021. url: https://dotnet.microsoft.com/ apps/xamarin.

51 A APPENDIX

A Appendix

A.1 Animation frame rate

Table 2: Native FPS Squares Nexus 5X Xperia Z2 100 58.88 54.87 200 54.00 31.05 300 49.08 22.51 400 40.97 15.83 500 33.89 15.53

Table 3: React Native FPS Squares Nexus 5X Xperia Z2 iPhone 7 100 57.85 58.25 52.58 200 55.75 54.20 47.40 300 55.03 46.75 51.15 400 52.13 35.18 53.05 500 50.73 26.03 47.18

Table 4: Native Android FPS VS React Native FPS Squares Native Android React Native 100 56.88 58.05 200 42.53 54.96 300 35.80 50.89 400 28.50 43.65 500 24.70 38.38

52 A APPENDIX

Table 5: Time in milliseconds for calculating Fibonacci(n) using the native Android application n Nexus 5X Xperia Z2 30 47.20 56.90 31 77.20 91.00 32 125.20 120.40 33 198.40 191.50 34 313.90 292.00 35 515.40 507.30 36 818.10 795.20 37 1326.80 1282.80 38 2152.60 2070.60 39 3517.10 3312.90 40 5711.90 5454.00 41 9056.70 8473.50

Table 6: Time in milliseconds for calculating Fibonacci(n) using the React Native application n Nexus 5X Xperia Z2 iPhone7 30 101.00 137.30 210.50 31 159.40 211.90 235.70 32 242.50 347.30 296.30 33 397.80 554.90 358.00 34 630.40 885.40 543.60 35 1009.40 1450.70 848.20 36 1634.70 2354.40 1354.10 37 2646.00 3775.10 2251.90 38 4251.50 6097.90 3505.00 39 7982.10 9796.80 5647.60 40 13 183.50 15 815.60 9162.20 41 23 570.70 25 003.80 14 713.10

A.2 Fibonacci sequence

53 A APPENDIX

Table 7: Native Android time VS React Native time n Native Android React Native 30 52.05 119.15 31 84.10 185.65 32 122.80 294.90 33 194.95 476.35 34 302.95 757.90 35 511.35 1230.05 36 806.65 1994.55 37 1304.80 3210.55 38 2111.60 5174.70 39 3415.00 8889.45 40 5582.95 14 499.55 41 8765.10 24 287.25

A.3 Matrix multiplication

Table 8: Time in milliseconds for a matrix multiplication of size n using the native Android application n Nexus 5X Xperia Z2 100 29.00 85.40 120 56.70 134.30 140 99.00 239.00 160 154.80 337.60 180 220.00 471.50 200 315.00 672.90 220 417.60 870.00 240 565.20 1146.40 260 2620.50 1947.70 280 4050.00 2418.10 300 5857.50 3136.00 320 8450.30 3525.70

54 A APPENDIX

Table 9: Time in milliseconds for a matrix multiplication of size n using the React Native application n Nexus 5X Xperia Z2 iPhone 7 100 1957.00 2974.70 393.90 120 3353.70 5127.60 660.80 140 5332.80 8104.70 1039.50 160 7990.10 12 079.90 1541.50 180 11 404.40 17 371.90 2193.00 200 15 748.50 23 935.60 2989.20 220 25 692.80 31 936.50 3995.40 240 37 715.30 41 881.90 5224.10 260 44 464.80 56 344.50 6717.88 280 56 761.70 70 059.70 9321.90 300 78 951.00 85 531.10 11 396.90 320 94 007.30 104 621.90 14 195.10

Table 10: Native Android time VS React Native time for matrix multiplica- tion n Native Android React Native 100 57.20 2465.85 120 95.50 4240.65 140 169.00 6718.75 160 246.20 10 035.00 180 345.75 14 388.15 200 493.95 19 842.05 220 643.80 28 814.65 240 855.80 39 798.60 260 2284.10 50 404.65 280 3234.05 63 410.70 300 4496.75 82 241.05 320 5988.00 99 314.60

A.4 Binary search tree insertion

55 A APPENDIX

Table 11: Time in milliseconds for inserting n nodes in a binary search tree using the native application n Nexus 5X Xperia Z2 10000 20.00 29.50 20000 71.40 62.00 30000 163.00 121.00 40000 293.60 214.40 50000 478.00 324.60 60000 690.80 456.40 70000 938.00 693.50 80000 1202.60 828.90 90000 1542.40 1005.00 100000 1782.80 1114.40 110000 2197.30 1299.70 120000 2601.20 1518.20

Table 12: Time in milliseconds for inserting n nodes in a binary search tree using the React Native application n Nexus 5X Xperia Z2 iPhone 7 10000 54.80 66.30 92.00 20000 123.50 157.10 134.00 30000 246.20 278.70 208.00 40000 410.10 446.00 229.00 50000 611.70 646.40 200.00 60000 892.40 876.20 324.00 70000 1178.00 1116.00 298.00 80000 1429.80 1376.80 345.00 90000 1715.80 1609.30 478.00 100000 1995.40 1860.50 463.00 110000 2276.50 2082.60 587.00 120000 2583.80 2351.90 652.00

56 A APPENDIX

Table 13: Time in milliseconds for inserting n nodes in a binary search tree using the native Android application versus the React Native application n Native Android React Native 10000 24.75 60.55 20000 66.70 140.30 30000 142.00 262.45 40000 254.00 428.05 50000 401.30 629.05 60000 573.60 884.30 70000 815.75 1147.00 80000 1015.75 1403.30 90000 1273.70 1662.55 100000 1448.60 1927.95 110000 1748.50 2179.55 120000 2059.70 2467.85

57 A APPENDIX

A.5 Array reverse

Table 14: Time in milliseconds for reversing an array of size n using the native Android application n Nexus 5X Xperia Z2 1000 59.20 39.00 1333 82.80 102.00 1666 140.00 186.00 2000 174.20 226.50 2333 199.20 267.00 2666 177.80 294.34 3000 231.40 342.79 3333 279.20 380.47 3666 335.40 497.00 4000 443.20 553.97 4333 473.80 639.35 4666 513.00 695.58

Table 15: Time in milliseconds for reversing an array of size n using the React Native application n Nexus 5X Xperia Z2 iPhone 7 1000 118.40 110.10 36.9 1333 206.30 196.60 50.4 1666 223.50 323.00 66.9 2000 279.70 431.50 75.6 2333 395.80 626.00 - 2666 528.90 866.10 - 3000 660.30 1104.50 - 3333 810.80 1365.30 - 3666 966.60 1631.30 - 4000 1124.90 1967.60 - 4333 1346.30 2347.80 - 4666 1554.20 2691.80 -

58 A APPENDIX

Table 16: Native Android time VS React Native time for reversing an array of size n n Native Android React Native 1000 49.10 114.25 1333 92.40 201.45 1666 163.00 273.25 2000 200.35 355.60 2333 233.10 510.90 2666 236.07 697.50 3000 287.10 882.40 3333 329.84 1088.05 3666 416.20 1298.95 4000 498.59 1546.25 4333 556.58 1847.05 4666 604.29 2123.00

59