Miikka Oksanen Cross-platform UI Development: React vs Svelte
Metropolia University of Applied Sciences Bachelor of Engineering Information and Communication Technology Bachelor’s Thesis 20 May 2021
Abstract
Author: Miikka Oksanen Title: Cross-platform UI Development: React vs Svelte Number of Pages: 79 pages Date: 20 May 2021
Degree: Bachelor of Engineering Degree Programme: Information and Communication Technology Professional Major: Software Engineering Instructors: Simo Silander, Senior Lecturer Tommi Lundell, R&D Squad Group Leader at Nokia Petteri Hiisilä, Senior Interaction Designer at Nokia
This thesis is part of a project done for Nokia. The goal was to gain insights about four UI frameworks - React, Svelte, React Native and Svelte Native - that will be used for determining which of the two native UI frameworks would be a better base for Nokia’s own native UI framework. Nokia’s native UI framework will be used to build customer applications for smartphones.
Each of the four frameworks was used to implement a front-end application GeoHub. The implementation processes were conducted with the purpose of gaining information about the development experience that the UI frameworks offer. Each GeoHub version (excluding GeoHub Svelte Native) was developed to the point that they could be considered completed.
The development experiences that the frameworks provided during the implementation of each GeoHub version were compared through five development experience attributes. React and React Native came out on top of their counterparts in this comparison. A major reason why Svelte and Svelte Native did not score as well as their counterparts was due to their immaturity. Thus, it was suggested that the progress of those technologies should be monitored.
It was also discovered that the amount of code that could be reused between web and the native implementations of GeoHub was low. The reason for this was deemed to be the extensive use of third party npm packages and the difference in display sizes between desktop and smartphone displays.
Tutkinto: Insinööri (AMK) Tutkinto-ohjelma: Tieto- ja viestintätekniikka Ammatillinen pääaine: Ohjelmistotuotanto Ohjaajat: Lehtori Simo Silander R&D tiimin johtaja (Nokia) Tommi Lundell Vuorovaikutussuunnitelija (Nokia) Petteri Hiisilä
Tämä opinnäytetyö on osa Nokialle tehtyä projektia. Projektin tavoitteena oli kerätä tietoa neljästä käyttöliittymäsovelluskehyksestä (React, Svelte, React Native, Svelte ja Svelte Native). Tätä tietoa käytetään apuna päättämään, kumpaa kahdesta natiivista sovelluskehyksestä (React Native, Svelte Native) kannattaa käyttää perustana Nokian omassa natiivissa sovelluskehyksessä. Nokian natiivia sovelluskehystä tullaan käyttämään asiakkaille suunnattujen älypuhelinsovellusten kehittämisessä.
Kullakin sovelluskehyksellä toteutettiin GeoHub-käyttöliittymäsovellus. Näiden prosessien tavoitteena oli kerätä tietoa kunkin sovelluskehyksen tarjoamasta kehittämiskokemuksesta. Kolme neljästä GeoHub-sovelluksesta saatiin kehitetyiksi hyväksyttävään tilaan. ”Svelte Native”:lla kehitettyä sovellusta ei saatu valmiiksi.
Sovelluskehyksien tarjoamia kehittämiskokemuksia vertailtiin viidessä osa- alueessa. React ja React Native pärjäsivät vastaosiaan paremmin vertailussa. Suuri syy, miksi Svelte ja Svelte Native eivät pärjänneet vertailussa, perustui niiden uutuuteen. Täten ehdotettiin, että näiden teknologioiden kehitystä olisi seurattava.
Todettiin myös, että kierrätettävän koodin määrä verkko- ja natiivitoteutuksien välillä oli alhainen. Syyksi nähtiin laaja kolmannen osapuolen npm-pakkauksien käyttö sekä näyttökokojen eroavaisuus pöytäkone- ja älypuhelinnäytöissä.
2.1 Definition 2 2.1.1 Cross-platform Software 2 2.1.2 UI and Its Development 3 2.2 Benefits of Using Cross-platform UI Frameworks 6 2.3 Problems Related to Cross-platform UI Development 7
3 React - Reigning King of UI Frameworks 11
3.1 History of React 11 3.2 Concepts 12 3.2.1 React Components 13 3.2.2 Virtual DOM 14 3.3 Syntax 16
4 React Native - Smartphone Servant of React 20
4.1 Origin Story 20 4.2 Adding “Native” to React 22 4.3 Syntax 23
5 Svelte - Odd Challenger 26
5.1 Performant Svelte 26 5.2 Not Your Traditional Web UI Framework 29 5.3 Reactive UIs with Svelte 30 5.4 Syntax 31 5.4.1 Reactive Statements with “$” Label 32 5.4.2 Value Bindings 33
6 Svelte Native - Work in Progress 34
6.1 Svelte Native and NativeScript 34 6.2 Syntax 36
7 Development Process 40
7.1 Development Environment and Version Control 40 7.2 Application Idea 41 7.3 Designing GeoHub 42 7.4 GeoHub 44 7.4.1 Use Cases 44 7.4.2 GeoHub UI in Screenshots 47 7.5 Implementation Processes 54 7.5.1 Evaluating Official Framework Documentation 55 7.5.2 Utilizing npm Packages 59 7.5.3 Framework Setup 60 7.5.4 Interactive Map with Leaflet 61 7.5.5 Reverse Engineering Nokia’s React components 62 7.5.6 Material Design UI Component Libraries 63 7.5.7 Working with React and Svelte 66 7.5.8 Working with React Native and Svelte Native 68
8 Conclusion and Future Plans 69
References 74
List of Abbreviations
UI: User interface. A two-way interaction layer between humans and machines.
HTML: HyperText Markup Language. A text-based markup language for defining web page structures.
CSS: Cascading Style Sheets. A text-based style sheet language for altering the appearance of a structure defined in a markup language.
XML: Extensible Markup Language. A standardized, text-based markup language for writing human- and machine-readable documents.
API: Application programming interface. A collection of related interfaces that defines how one can interact with the software or hardware that owns it.
DOM: Document Object Model. A data representation of the structure and contents defined in a HTML or XML file.
APK: Android package. An installation file containing a single Android application.
AST: Abstract syntax tree. A data structure representing source code structure which is commonly used by compilers for analysing semantic correctness of source code. npm: Node package manager. A collection of JavaScript software tools that automate the process of installing, removing and updating JavaScript software packages.
IDE: Integrated development environment. Software that provides tools for efficient software development.
1
1 Introduction
Nokia is looking to create a mobile-app development framework to support their existing web app framework. The framework will be used to create mobile applications that support the presentation of Nokia’s products to potential customers. Additionally, the framework should either work with Nokia’s existing web application framework which was built using React or be good enough to warrant the modification of their web framework. This is because the mobile framework would also be used to make smartphone application versions of existing Nokia web applications.
The task was to evaluate two native UI frameworks, React Native and Svelte Native, as potential candidates to act as a base for Nokia’s smartphone UI development framework. Consequently, the web UI frameworks React and Svelte needed to be examined as well as the native UI frameworks are based on them. The focus was to be on the developer experience these technologies provide.
An ambitious plan was made to evaluate the frameworks. It consisted of building four similar applications, two web applications with React and Svelte and two smartphone applications with React Native and Svelte Native. During this process, the pros and cons of the technologies would be documented. Once completed, convincing arguments could be presented with documentation to back them up.
2 Cross-platform UI Development
Before introducing each of the UI frameworks, it is good to have an understanding on where and how they can be used. This chapter also introduces more precise definitions for some of the more ambiguous terms used in the thesis.
2
2.1 Definition
The term “cross-platform UI development” means the development of UIs that work on multiple platforms [1]. To properly define the term, it needs to be broken down into two parts: Cross-platform software and UI development.
2.1.1 Cross-platform Software
Cross-platform software, by definition, refers to a piece of software that has been implemented in a way where it will work on multiple computing platforms. A computing platform is simply an environment where software can be run. Operating systems, web browsers and hardware are all examples of computing platforms. A single computing device typically contains multiple layers of computing platforms. For example, a piece of hardware runs an operating system which in turn runs a web browser. [1.]
There are many ways to write cross-platform software. In the early days, developers implemented separate versions for each computing platform. This way of development was costly and slow as each version required developers that had knowledge of the inner workings of the underlying platform. Nowadays the process is much more efficient due to connecting interfaces that abstract the difference between computing platforms. [1.]
In this thesis, the platforms in the term cross-platform are narrowed down to smartphone operating systems and web browsers in general unless explicitly stated otherwise. This is due to the lack of a better suited term in the technological terminology. Consequently, the term cross-platform UI framework refers to a software that is used to build UIs for web browser applications and applications running on smartphone operating systems.
The UI frameworks that are discussed in this thesis are not cross-platform UI frameworks when considered individually. This, however, changes when they are coupled together. The first couple being React and React Native, and the second
3 being Svelte and Svelte Native. This coupling will start to make sense later when the similarities between the web application UI and smartphone application UI frameworks are discussed in detail.
The usage of the word “native” in the names of the UI frameworks discussed in here can be a little confusing. Native software is commonly defined to be software that runs on a specific operating system [2]. However, both React Native and Svelte Native are used to build UIs that can run on at least Android and iOS smartphone operating systems [3; 4]. Hence, the word native is used in the thesis to refer to smartphone operating systems in general.
2.1.2 UI and Its Development
A UI can be split into two interconnected representations. The first representation is known as the data representation which resides in hardware memory. This representation is called UI data tree here. It is typically a tree data structure consisting of UI element nodes. The implementation of a UI data tree typically varies between computing platforms. Concretely this means that the same methods cannot be used to work with for example, a web browser UI data tree and an Android UI data tree.
UI developers write code that acts as instructions determining what the UI data tree should look like at a given moment. The amount of detail UI developers need to put into the instructions depends on the used tools and target computing platform. As an example, conditionally adding a specific node to the web browser’s UI data tree requires three consecutive instructions, when communicating directly with the web browser: Create the new node, find the desired position of the new node on the UI data tree and finally add the node to the UI data tree (Listing 1).
4 if (someCondition) { // 1. Create new node const newNode = document.createElement(“div”) // 2. Find the desired position on the UI data tree const parentNode = document.querySelector(“#parent”) // 3. Add the new node to the UI data tree parentNode.append(newNode) }
Listing 1. Adding a new node to the web browser’s UI data tree without UI frameworks.
Declarative web UI frameworks such as React wrap the three instructions shown in Listing 1 into a single instruction as can be seen in Listing 2.
{someCondition ? : “”}
Listing 2. Adding a new node to the web browser’s UI data tree by using React.
UI data tree is a new term that was invented for the thesis due to the lack of a fitting term in the technical terminology. It was invented for the purpose of discussing the way different computing platforms manage UIs in a general manner. The fundamental job of UI frameworks is to make issuing instructions to UI data tree implementations more convenient for UI developers. And since the UI frameworks discussed here target web browsers and smartphone operating systems, finding a general term for referring to the way those computing platforms manage UIs is essential.
The second UI representation is called the visual representation. This is what users see on their screens when they open an application. The visual representation gets built from the data representation in a process called rendering. Rendering is a computationally expensive process as it involves calculating UI element positions and painting them on screen [5].
User interactions on the UI do not directly affect the visual representation. A user interaction, otherwise known as a user event, gets translated into instructions that modify the UI data tree. It is only on the next render that the user gets to see the result of their actions on the screen.
5
Figure 1 describes the two UI representations. The UI data tree on the left side contains three nodes: one root node and two leaf nodes. The UI data tree that resides in hardware memory gets rendered into a visual representation consisting of pixels. The pixels are visible to the user of the UI through a monitor. In Figure 1 below, the leaf nodes are rendered inside and on top of the red root node. Although this is how UI data tree implementations are typically rendered by default, the computing platforms often offer ways for developers to alter this rendering schema [6].
Figure 1. UI data representation is rendered into a visual representation.
UI development is a process where UI developers design and implement a user interface, usually for an application. The process input is a list of features and design guidelines. The process output is a UI that contains the given features and follows the given design guidelines. [7.]
The process commonly starts with UI developers choosing a set of appropriate UI elements and styles. The developers then choose a layout for the visual elements so that the result looks visually pleasing and coherent. The layout should enable users to perform their desired actions with relative ease. [7] Once the UI design is set, the developers can start implementing the UI, often with the help of UI frameworks.
6
2.2 Benefits of Using Cross-platform UI Frameworks
Cross-platform UI frameworks allow entities to efficiently develop and maintain applications that reach an audience spanning across web browsers and smartphones. This is especially desirable for for-profit organizations that are constantly trying to attract customers in a cost-efficient way.
Having software products available on several platforms also brings companies security against changes in userbase behaviour. Facebook’s signature social media application is a good example of this. The application launched solely on the web platform in 2004 but over the years, the userbase of the application has shifted dramatically towards using the smartphone version as can be seen on Figure 2. [8].
Figure 2. Facebook’s userbase across different devices [9].
By using cross-platform UI frameworks, developers have an easier time implementing and maintaining UI code for multiple platforms. They can share
7 code between implementations targeting different platforms and thus need to spend less time making modifications to their codebases [1].
Another benefit is the reduced amount of knowledge needed to develop UIs for multiple platforms. Web application development traditionally requires the knowledge of HTML, CSS and JavaScript [10]. For traditional native application development, one needs to know the following languages: XML for both Android and iOS, Java or Kotlin for Android application development and Swift or Objective-C for iOS application development [11; 12]. JavaScript native UI frameworks such as React Native enable web developers to quickly start developing native applications without the need to learn native programming languages.
Cross-platform UI frameworks are beneficial for software companies in all maturity levels. New companies and start-ups use them to get their commercial applications “out there” as fast as possible to as many people as possible. As these companies grow their product catalogue, they do not need hire as many developers to maintain their products.
Potential savings have motivated top software companies to develop their own cross-platform UI frameworks. Both Google and Facebook have developed their own cross-platform JavaScript UI frameworks, Angular and React together with React Native, which have later been open-sourced [13; 14].
2.3 Problems Related to Cross-platform UI Development
Most cross-platform UI frameworks have separate UI element lists for web browser and native platforms, meaning that developers need to specify at least two different UI structures when developing cross-platform UIs [1]. Although the UI element APIs that the platforms expose offer a similar selection of elements, the instantiation between related elements often differs.
8
Listings 3 and 4 contain instantiations for UI elements that are used for displaying images. Listing 3 instantiates an Android ”ImageView” UI element in XML with a width and height of 200 pixels. The image that is shown to the user is defined by the “android:src” attribute. Its value contains a path to an image file. The “android:contentDescription” attribute is used for attaching an alternative text description to the shown image.
Listing 3. An XML code snippet for instantiating an Android image UI element.
Listing 4 contains an instantiation for a similar image UI element that was instantiated in Listing 3 above. But the instantiation in Listing 4 is for an “img” web UI element that is written in HTML. Both instantiations have the same bounds, but the “width” and “height” attributes of the “img” UI element are automatically measured as pixels, so there is no need to add the “px” suffix.
Listing 4. A HTML code snippet for instantiating a web image UI element.
Listings 3 and 4 above have different source image paths (“src” attributes). The source image path of the web UI element leads to an image file that is accessed through the web. Smartphone applications do not have the luxury of having guaranteed internet access which is why using resources that are hosted in a web server should be avoided whenever possible. The source image path of the Android image element points to a file that is packed together with the application that uses the element. This way the image file is available regardless of whether internet is available or not.
9
Then there is the difference in screen sizes between desktop monitors and smartphone screens. The common desktop aspect ratio is 16:9 meaning that for every 16 pixels in the horizontal direction, there are nine vertical pixels. Smartphones held in a vertical orientation usually have the same aspect ratio but reversed (9:16). This means that in the design phase of UI development, UI developers usually come up with two UI layouts, one for each aspect ratio. [15.]
Listings 5 and 6 showcase a problem that the difference in aspect ratios can cause. They define seemingly equivalent UIs for Android (Listing 5) and web (Listing 6). Listing 5 contains some necessary XML boilerplate code, but the important part is the “TextView” UI element instantiation, or more specifically, the “android:layout_width” and “android:layout_height” properties. These properties are used to specify the bounds of the “TextView” UI element.
Listing 5. A simple Android UI definition in XML.
The web UI definition (Listing 6) is more concise and readable than the Android UI definition (Listing 5). The “p” UI element in Listing 6 has the same bounds as the “TextView” UI element in Listing 5.
Hello World!
Listing 6. A simple web UI definition in HTML.
Figures 3 and 4 display the corresponding visual UI representations for Listings 5 and 6. The Android UI code was run on an Android smartphone emulator with
10 a width of 1440 pixels and a height of 2560 pixels, giving it an aspect ratio of 9:16. The web UI code was run on a desktop display with an aspect ratio of 16:9. The text in the Android “TextView” UI element was not rendered into a single line (Figure 3) because it would have been longer than its width, which was set to be 200 pixels.
Figure 3. Cropped screenshot of the visual representation of the simple Android UI defined in Listing 5.
The visual representation of the web UI shown in Figure 4 has the “Hello world!” text in a single line. The text fits on a single line because of the aspect ratio of the desktop monitor.
Figure 4. Cropped screenshot of the visual representation of the simple web UI defined in Listing 6.
It is also worth noting that the text in the visual Android UI representation is tightly glued to the left side of the screen while the web UI text has a small left offset. This is because web browsers have an inherent CSS stylesheet known as the user agent stylesheet [16]. The user agent stylesheet contains a CSS rule that adds a margin of eight pixels to the “body” element.
11
Because of the problems stated above, the dream of having one codebase to “rule them all” when it comes to cross-platform UIs is often not a realistic one, even with the help of cross-platform UI frameworks. While abstracting away the differences between the APIs that different computing platforms offer for features such as button press handling is trivial, things become more complicated when trying combine entire UI data tree APIs under a single abstract API. This is one of the main reasons why both React and Svelte have separate native versions.
3 React - Reigning King of UI Frameworks
React was the second most popular web framework among all the programming languages according to the Stack Overflow’s 2020 developer survey [17]. Therefore, it is no surprise that one can easily find countless articles and blog posts describing what React is. But in order to fully appreciate the technology, it is essential to know how React came to be and what problems was it built to solve.
3.1 History of React
The cause that facilitated the birth of React came from Facebook’s advertisement division’s (Facebook Ad Org’s) trouble maintaining their ever-growing web applications. As is often the case with software projects, each update and feature that the developers added made their projects more complicated and thus made the development process slower. [18.]
There was one effect in particular that was causing the developers problems, called “cascading updates”. Facebook Ad Org’s web application UIs were built according to the traditional MVC (Model View Controller) pattern where each application UI would have a UI entity tree. A UI entity tree is essentially an extension to the UI data tree which allows tree nodes to contain their own logic and pass data between each other. [19.]
12
The UI entities were very tightly coupled, where entity controllers passed data up and down the tree. When the controller of an entity received new data, the model of the entity needed to decide whether to update the view of the entity. Because of the dependency relationship between the UI entity tree nodes, every other related entity needed to undergo the same process. This often cascaded across the whole tree, hence the name “cascading updates”. [19.]
The Facebook Ad Org developers had a hard time keeping track of all the UI entities which made it difficult to update application codebases reliably. Cascading updates meant that a modification in the code of a single UI entity could change the behaviour of UI entities that were several relations away. [19.]
The people at Facebook came up with a simple yet brilliant approach to UI entity trees that effectively solved the problems caused by cascading updates. Instead of modifying UI entities when they received new data, they would be instantiated again with the new data. This way developers did not need to know the previous data that the UI entity had, making the UI entities far simpler to understand. [19.]
With this approach, updates on a UI entity would only affect the UI entity and its children. As a UI entity was instantiated with new data, its children were also instantiated again. This was necessary, as updated data in a parent UI entity might be used in its children. As a result, updates on a UI entity deep in the tree would not cascade across the tree. [19.]
React was founded on top of this approach in 2011. It was open-sourced two years after its initial release and nowadays React is known to be a reliable and effective tool to build user interfaces. [18.]
3.2 Concepts
Although it is unclear whether the following concepts were first invented by the React team, it is clear is that React was the first web UI framework to utilize these concepts to a great effect.
13
3.2.1 React Components
React components are React’s take on UI entities, packaging structure, styling and logic in one function or class definition. They effectively replace the old MVC pattern where one would need to define a model, a view and a controller separately. In React, developers define component trees much like in the MVC pattern. But the relations between components are more clearly defined, which makes the code easier to maintain and update.
When one writes HTML code inside a React component definition, they are declaring React element instantiations. React elements are JavaScript objects that are used to describe a component instance and its properties. They are eventually transformed into DOM elements that are the building blocks of web UI data trees. [20.]
Each React component can have a state that controls when it should be updated. A component state is a JavaScript object which should not be mutated directly. Instead, one can change the state of a component by calling a specific function “setState” and providing a JavaScript object representing the new state as the argument to that function. Any “setState” call will be followed by React invoking its rendering library’s “render” method. As a result, the rendering library ReactDOM builds a new virtual UI data tree. [21.] The function name “render” is a bit misleading as it is not the same as building a visual representation of a UI from a UI data tree.
Figure 5 contains a diagram that shows how that visually demonstrates the information described in the previous paragraph. It shows how a state of a component gets mutated from its initial state through a “setState” call. The “setState” function definition includes a “render” function call.
14
Figure 5. Mutating a component’s state in React triggers a React rendering process [22].
Much like class constructors and functions, components can take input parameters known as “props” which is short for properties. Props are quite similar with component states, in that they are both JavaScript objects and updating them causes React to call its rendering library. The key difference is that a state is managed by the component that declared it while props are managed by the parent component that passed them. A component receiving props should consider them to be immutable. [21.]
3.2.2 Virtual DOM
When a web browser navigates to a valid web address, it makes an HTTP- request to a server. The server responds to the browser, returning a HTML document and any potential linked files like CSS and JavaScript files. The
15 browser then reads the HTML document into a UI data tree implementation known as the DOM. [5.]
Figure 6 shows how a web UI definition written in HTML looks like after it has been transformed to a DOM by a browser. The UI definition contains three container web UI element instantiations: “”, “